aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/General/gen_ff
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/General/gen_ff')
-rw-r--r--Src/Plugins/General/gen_ff/AlbumArt.cpp561
-rw-r--r--Src/Plugins/General/gen_ff/AlbumArt.h115
-rw-r--r--Src/Plugins/General/gen_ff/MediaDownloader.cpp307
-rw-r--r--Src/Plugins/General/gen_ff/README.txt6
-rw-r--r--Src/Plugins/General/gen_ff/WinampConfigScriptObject.cpp276
-rw-r--r--Src/Plugins/General/gen_ff/WinampConfigScriptObject.h99
-rw-r--r--Src/Plugins/General/gen_ff/api__gen_ff.h20
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/library-hilited.pngbin0 -> 1307 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/library-selected.pngbin0 -> 1306 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/library-unselected.pngbin0 -> 1304 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/mb-hilited.pngbin0 -> 1424 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/mb-selected.pngbin0 -> 1382 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/mb-unselected.pngbin0 -> 1428 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/pledit-hover.pngbin0 -> 828 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/pledit-selected.pngbin0 -> 807 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/pledit-unselected.pngbin0 -> 826 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/video-hilited.pngbin0 -> 1441 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/video-selected.pngbin0 -> 1435 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/video-unselected.pngbin0 -> 1439 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/vis-hilited.pngbin0 -> 3241 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/vis-selected.pngbin0 -> 3509 bytes
-rw-r--r--Src/Plugins/General/gen_ff/bitmaps/vis-unselected.pngbin0 -> 3037 bytes
-rw-r--r--Src/Plugins/General/gen_ff/embedwndguid.cpp200
-rw-r--r--Src/Plugins/General/gen_ff/embedwndguid.h42
-rw-r--r--Src/Plugins/General/gen_ff/ff_ipc.cpp535
-rw-r--r--Src/Plugins/General/gen_ff/ff_ipc.h86
-rw-r--r--Src/Plugins/General/gen_ff/fsmonitor.cpp174
-rw-r--r--Src/Plugins/General/gen_ff/fsmonitor.h39
-rw-r--r--Src/Plugins/General/gen_ff/gen.h1
-rw-r--r--Src/Plugins/General/gen_ff/gen_ff.rc543
-rw-r--r--Src/Plugins/General/gen_ff/gen_ff.rc258
-rw-r--r--Src/Plugins/General/gen_ff/gen_ff.sln204
-rw-r--r--Src/Plugins/General/gen_ff/gen_ff.vcxproj988
-rw-r--r--Src/Plugins/General/gen_ff/gen_ff.vcxproj.filters2074
-rw-r--r--Src/Plugins/General/gen_ff/gen_ff_ipc.h20
-rw-r--r--Src/Plugins/General/gen_ff/main.cpp3527
-rw-r--r--Src/Plugins/General/gen_ff/main.h29
-rw-r--r--Src/Plugins/General/gen_ff/menuactions.cpp787
-rw-r--r--Src/Plugins/General/gen_ff/menuactions.h91
-rw-r--r--Src/Plugins/General/gen_ff/minibrowserCOM.cpp93
-rw-r--r--Src/Plugins/General/gen_ff/minibrowserCOM.h25
-rw-r--r--Src/Plugins/General/gen_ff/precomp__gen_ff.cpp7
-rw-r--r--Src/Plugins/General/gen_ff/precomp__gen_ff.h76
-rw-r--r--Src/Plugins/General/gen_ff/prefs.cpp136
-rw-r--r--Src/Plugins/General/gen_ff/prefs.h30
-rw-r--r--Src/Plugins/General/gen_ff/prefs_about.cpp98
-rw-r--r--Src/Plugins/General/gen_ff/prefs_alpha.cpp280
-rw-r--r--Src/Plugins/General/gen_ff/prefs_colorthemes.cpp101
-rw-r--r--Src/Plugins/General/gen_ff/prefs_font.cpp860
-rw-r--r--Src/Plugins/General/gen_ff/prefs_general.cpp273
-rw-r--r--Src/Plugins/General/gen_ff/resource.h261
-rw-r--r--Src/Plugins/General/gen_ff/servicelink.cpp72
-rw-r--r--Src/Plugins/General/gen_ff/skininfo.cpp141
-rw-r--r--Src/Plugins/General/gen_ff/skininfo.h42
-rw-r--r--Src/Plugins/General/gen_ff/wa2buckitems.cpp96
-rw-r--r--Src/Plugins/General/gen_ff/wa2buckitems.h70
-rw-r--r--Src/Plugins/General/gen_ff/wa2cfgitems.cpp306
-rw-r--r--Src/Plugins/General/gen_ff/wa2cfgitems.h137
-rw-r--r--Src/Plugins/General/gen_ff/wa2core.cpp930
-rw-r--r--Src/Plugins/General/gen_ff/wa2core.h147
-rw-r--r--Src/Plugins/General/gen_ff/wa2coreactions.cpp279
-rw-r--r--Src/Plugins/General/gen_ff/wa2coreactions.h6
-rw-r--r--Src/Plugins/General/gen_ff/wa2frontend.cpp1344
-rw-r--r--Src/Plugins/General/gen_ff/wa2frontend.h359
-rw-r--r--Src/Plugins/General/gen_ff/wa2groupdefs.cpp36
-rw-r--r--Src/Plugins/General/gen_ff/wa2groupdefs.h18
-rw-r--r--Src/Plugins/General/gen_ff/wa2playlist.cpp2
-rw-r--r--Src/Plugins/General/gen_ff/wa2playlist.h11
-rw-r--r--Src/Plugins/General/gen_ff/wa2pldirobj.cpp366
-rw-r--r--Src/Plugins/General/gen_ff/wa2pldirobj.h105
-rw-r--r--Src/Plugins/General/gen_ff/wa2pledit.cpp241
-rw-r--r--Src/Plugins/General/gen_ff/wa2pledit.h68
-rw-r--r--Src/Plugins/General/gen_ff/wa2songticker.cpp483
-rw-r--r--Src/Plugins/General/gen_ff/wa2songticker.h108
-rw-r--r--Src/Plugins/General/gen_ff/wa2wndembed.cpp946
-rw-r--r--Src/Plugins/General/gen_ff/wa2wndembed.h223
-rw-r--r--Src/Plugins/General/gen_ff/wasabi.dsp1931
-rw-r--r--Src/Plugins/General/gen_ff/wasabi.vcproj286
-rw-r--r--Src/Plugins/General/gen_ff/wasabicfg.h491
79 files changed, 22266 insertions, 0 deletions
diff --git a/Src/Plugins/General/gen_ff/AlbumArt.cpp b/Src/Plugins/General/gen_ff/AlbumArt.cpp
new file mode 100644
index 00000000..90fba9da
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/AlbumArt.cpp
@@ -0,0 +1,561 @@
+#include "precomp__gen_ff.h"
+
+#include <api/core/api_core.h>
+#include "main.h"
+#include "AlbumArt.h"
+#include "wa2frontend.h"
+#include <api.h>
+#include <tataki/bitmap/bitmap.h>
+#include <api\wnd\notifmsg.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/script.h>
+
+#define ALBUMART_MAX_THREADS 4
+
+const wchar_t albumArtXuiObjectStr[] = L"AlbumArt"; // This is the xml tag
+char albumArtXuiSvcName[] = "Album Art XUI object"; // this is the name of the xuiservice
+
+AlbumArtScriptController _albumartController;
+AlbumArtScriptController *albumartController = &_albumartController;
+
+BEGIN_SERVICES( wa2AlbumArt_Svcs );
+DECLARE_SERVICE( XuiObjectCreator<AlbumArtXuiSvc> );
+END_SERVICES( wa2AlbumArt_Svcs, _wa2AlbumArt_Svcs );
+
+// --------------------------------------------------------
+// Maki Script Object
+// --------------------------------------------------------
+
+// -- Functions table -------------------------------------
+function_descriptor_struct AlbumArtScriptController::exportedFunction[] = {
+ {L"refresh", 0, (void *)AlbumArt::script_vcpu_refresh },
+ {L"onAlbumArtLoaded", 1, (void *)AlbumArt::script_vcpu_onAlbumArtLoaded },
+ {L"isLoading", 0, (void *)AlbumArt::script_vcpu_isLoading },
+};
+
+const wchar_t *AlbumArtScriptController::getClassName()
+{
+ return L"AlbumArtLayer";
+}
+
+const wchar_t *AlbumArtScriptController::getAncestorClassName()
+{
+ return L"Layer";
+}
+
+ScriptObject *AlbumArtScriptController::instantiate()
+{
+ AlbumArt *a = new AlbumArt;
+
+ ASSERT( a != NULL );
+
+ return a->getScriptObject();
+}
+
+void AlbumArtScriptController::destroy( ScriptObject *o )
+{
+ AlbumArt *a = static_cast<AlbumArt *>( o->vcpu_getInterface( albumArtGuid ) );
+
+ ASSERT( a != NULL );
+
+ delete a;
+}
+
+void *AlbumArtScriptController::encapsulate( ScriptObject *o )
+{
+ return NULL; // no encapsulation yet
+}
+
+void AlbumArtScriptController::deencapsulate( void *o )
+{}
+
+int AlbumArtScriptController::getNumFunctions()
+{
+ return sizeof( exportedFunction ) / sizeof( function_descriptor_struct );
+}
+
+const function_descriptor_struct *AlbumArtScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID AlbumArtScriptController::getClassGuid()
+{
+ return albumArtGuid;
+}
+
+
+XMLParamPair AlbumArt::params[] =
+{
+ {ALBUMART_NOTFOUNDIMAGE, L"NOTFOUNDIMAGE"},
+ {ALBUMART_SOURCE, L"SOURCE"},
+ {ALBUMART_VALIGN, L"VALIGN"},
+ {ALBUMART_ALIGN, L"ALIGN"},
+ {ALBUMART_STRETCHED, L"STRETCHED"},
+ {ALBUMART_NOREFRESH, L"NOAUTOREFRESH"},
+};
+
+class AlbumArtThreadContext
+{
+ public:
+ AlbumArtThreadContext( const wchar_t *_filename, AlbumArt *_wnd )
+ {
+ /* lazy load these two handles */
+ if ( !_wnd->hMainThread )
+ _wnd->hMainThread = WASABI_API_APP->main_getMainThreadHandle();
+
+ if ( !_wnd->thread_semaphore )
+ _wnd->thread_semaphore = CreateSemaphore( 0, ALBUMART_MAX_THREADS, ALBUMART_MAX_THREADS, 0 );
+
+ wnd = _wnd;
+ iterator = wnd->iterator;
+ h = w = 0;
+ bits = 0;
+ filename = _wcsdup( _filename );
+ }
+
+ void FreeBits()
+ {
+ if ( bits )
+ WASABI_API_MEMMGR->sysFree( bits );
+
+ bits = 0;
+ }
+
+ ~AlbumArtThreadContext()
+ {
+ if ( wnd )
+ {
+ if ( wnd->thread_semaphore )
+ ReleaseSemaphore( wnd->thread_semaphore, 1, 0 );
+
+ wnd->isLoading--;
+ }
+
+ free( filename );
+ }
+
+ static void CALLBACK AlbumArtNotifyAPC( ULONG_PTR p );
+ bool LoadArt();
+
+ int h;
+ int w;
+ ARGB32 *bits;
+ LONG iterator;
+ wchar_t *filename;
+ AlbumArt *wnd;
+};
+
+
+AlbumArt::AlbumArt()
+{
+ getScriptObject()->vcpu_setInterface( albumArtGuid, ( void * )static_cast<AlbumArt *>( this ) );
+ getScriptObject()->vcpu_setClassName( L"AlbumArtLayer" );
+ getScriptObject()->vcpu_setController( albumartController );
+
+ WASABI_API_MEDIACORE->core_addCallback( 0, this );
+
+ w = 0;
+ h = 0;
+ iterator = 0;
+ bits = 0;
+ hMainThread = 0;
+ thread_semaphore = 0;
+ artBitmap = 0;
+ valign = 0;
+ align = 0;
+ stretched = false;
+ missing_art_image = L"winamp.cover.notfound"; // default to this.
+ src_file = L"";
+ forceRefresh = false;
+ noAutoRefresh = false;
+ noMakiCallback = false;
+ isLoading = 0;
+
+ /* register XML parameters */
+ xuihandle = newXuiHandle();
+
+ CreateXMLParameters( xuihandle );
+}
+
+void AlbumArt::CreateXMLParameters( int master_handle )
+{
+ //ALBUMART_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof( params ) / sizeof( params[ 0 ] );
+ hintNumberOfParams( xuihandle, numParams );
+
+ for ( int i = 0; i < numParams; i++ )
+ addParam( xuihandle, params[ i ], XUI_ATTRIBUTE_IMPLIED );
+}
+
+
+AlbumArt::~AlbumArt()
+{
+ WASABI_API_SYSCB->syscb_deregisterCallback( static_cast<MetadataCallbackI *>( this ) );
+ WASABI_API_MEDIACORE->core_delCallback( 0, this );
+
+ // wait for all of our threads to finish
+ InterlockedIncrement( &iterator ); // our kill switch (will invalidate iterator on all outstanding threads)
+ if ( thread_semaphore )
+ {
+ for ( int i = 0; i < ALBUMART_MAX_THREADS; i++ )
+ {
+ if ( WaitForMultipleObjectsEx( 1, &thread_semaphore, FALSE, INFINITE, TRUE ) != WAIT_OBJECT_0 )
+ i--;
+ }
+ }
+
+ delete artBitmap;
+
+ if ( bits )
+ WASABI_API_MEMMGR->sysFree( bits );
+
+ if ( thread_semaphore )
+ CloseHandle( thread_semaphore );
+
+ if ( hMainThread )
+ CloseHandle( hMainThread );
+}
+
+bool AlbumArt::layer_isInvalid()
+{
+ return !bits;
+}
+
+void CALLBACK AlbumArtThreadContext::AlbumArtNotifyAPC( ULONG_PTR p )
+{
+ AlbumArtThreadContext *context = (AlbumArtThreadContext *)p;
+ if ( context->wnd->iterator == context->iterator )
+ context->wnd->ArtLoaded( context->w, context->h, context->bits );
+ else
+ context->FreeBits();
+
+ delete context;
+}
+
+bool AlbumArtThreadContext::LoadArt()
+{
+ if ( wnd->iterator != iterator )
+ return false;
+
+ if ( AGAVE_API_ALBUMART->GetAlbumArt( filename, L"cover", &w, &h, &bits ) != ALBUMART_SUCCESS )
+ {
+ bits = 0;
+ w = 0;
+ h = 0;
+ }
+
+ if ( wnd->iterator == iterator ) // make sure we're still valid
+ {
+ QueueUserAPC( AlbumArtNotifyAPC, wnd->hMainThread, (ULONG_PTR)this );
+
+ return true;
+ }
+ else
+ {
+ FreeBits();
+
+ return false;
+ }
+}
+
+static int AlbumArtThreadPoolFunc( HANDLE handle, void *user_data, intptr_t id )
+{
+ AlbumArtThreadContext *context = (AlbumArtThreadContext *)user_data;
+ if ( context->LoadArt() == false )
+ {
+ delete context;
+ }
+
+ return 0;
+}
+
+void AlbumArt::ArtLoaded( int _w, int _h, ARGB32 *_bits )
+{
+ if ( bits )
+ WASABI_API_MEMMGR->sysFree( bits );
+
+ if ( artBitmap )
+ {
+ delete artBitmap;
+ artBitmap = 0;
+ }
+
+ bits = _bits;
+ w = _w;
+ h = _h;
+
+ if ( !bits )
+ {
+ SkinBitmap *albumart = missing_art_image.getBitmap();
+ if ( albumart )
+ {
+ w = albumart->getWidth();
+ h = albumart->getHeight();
+ }
+ }
+
+ deleteRegion();
+ makeRegion();
+ notifyParent( ChildNotify::AUTOWHCHANGED );
+ invalidate();
+
+ // notify maki scripts that albumart has been found or not
+ if ( !noMakiCallback && _bits )
+ {
+ AlbumArt::script_vcpu_onAlbumArtLoaded( SCRIPT_CALL, this->getScriptObject(), MAKE_SCRIPT_BOOLEAN( (int)bits ) );
+ }
+}
+
+void AlbumArt::onSetVisible( int show )
+{
+ if ( show )
+ {
+ corecb_onUrlChange( wa2.GetCurrentFile() );
+ }
+ else
+ {
+ if ( bits )
+ {
+ WASABI_API_MEMMGR->sysFree( bits );
+
+ delete artBitmap;
+ artBitmap = 0;
+ }
+
+ bits = 0;
+ }
+}
+
+int AlbumArt::corecb_onUrlChange( const wchar_t *filename )
+{
+ // Martin> if we call this from maki we want to do a refresh regardless of the albumartlayer being visible or not
+ if ( forceRefresh || ( !noAutoRefresh && isVisible() ) )
+ {
+ isLoading++;
+
+ // Martin > do a check for a specific file, defined via source param
+ if ( WCSICMP( src_file, L"" ) )
+ filename = src_file;
+
+ InterlockedIncrement( &iterator );
+ AlbumArtThreadContext *context = new AlbumArtThreadContext( filename, this );
+
+ // make sure we have an available thread free (wait for one if we don't)
+ while ( WaitForMultipleObjectsEx( 1, &thread_semaphore, FALSE, INFINITE, TRUE ) != WAIT_OBJECT_0 )
+ {}
+
+ // int vis__ = isVisible();
+ WASABI_API_THREADPOOL->RunFunction( 0, AlbumArtThreadPoolFunc, context, 0, api_threadpool::FLAG_LONG_EXECUTION );
+ }
+
+ return 1;
+}
+
+int AlbumArt::onInit()
+{
+ int r = ALBUMART_PARENT::onInit();
+ WASABI_API_SYSCB->syscb_registerCallback( static_cast<MetadataCallbackI *>( this ) );
+
+ AlbumArt::corecb_onUrlChange( wa2.GetCurrentFile() );
+
+ return r;
+}
+
+int AlbumArt::skincb_onColorThemeChanged( const wchar_t *newcolortheme )
+{
+ ALBUMART_PARENT::skincb_onColorThemeChanged( newcolortheme );
+ invalidate();
+
+ return 0;
+}
+
+SkinBitmap *AlbumArt::getBitmap()
+{
+ if ( artBitmap )
+ return artBitmap;
+
+ if ( bits )
+ {
+ artBitmap = new HQSkinBitmap( bits, w, h ); //TH WDP2-212
+
+ return artBitmap;
+ }
+
+ return missing_art_image.getBitmap();
+}
+
+void AlbumArt::layer_adjustDest( RECT *r )
+{
+ if ( !w || !h )
+ return;
+
+ if ( stretched )
+ return;
+
+ //getClientRect(r);
+ // maintain 'square' stretching
+ int dstW = r->right - r->left;
+ int dstH = r->bottom - r->top;
+ double aspX = (double)( dstW ) / (double)w;
+ double aspY = (double)( dstH ) / (double)h;
+ double asp = min( aspX, aspY );
+ int newW = (int)( w * asp );
+ int newH = (int)( h * asp );
+
+ // Align
+ int offsetX = ( dstW - newW ) / 2;
+ if ( align == 1 )
+ offsetX *= 2;
+ else if ( align == -1 )
+ offsetX = 0;
+
+ // Valign
+ int offsetY = ( dstH - newH ) / 2;
+ if ( valign == 1 )
+ offsetY *= 2;
+ else if ( valign == -1 )
+ offsetY = 0;
+
+ r->left += offsetX;
+ r->right = r->left + newW;
+ r->top += offsetY;
+ r->bottom = r->top + newH;
+
+ // This prevents parts of the image being cut off (if the img has the same dimensions as the rect) on moving/clicking winamp
+ // (they will just flicker, but at least they won't stay now)
+ // benski> CUT!!! no no no no no this is very bad because this gets called inside layer::onPaint
+ //invalidate();
+}
+/*
+int AlbumArt::getWidth()
+{
+ RECT r;
+ getClientRect(&r);
+ getDest(&r);
+ return r.right-r.left;
+}
+
+int AlbumArt::getHeight()
+{
+ RECT r;
+ getClientRect(&r);
+ getDest(&r);
+ return r.bottom-r.top;
+}
+*/
+/*
+int AlbumArt::onPaint(Canvas *canvas)
+{
+ ALBUMART_PARENT::onPaint(canvas);
+ if (bits)
+ {
+ SkinBitmap albumart(bits, w, h);
+ RECT dst;
+ getBufferPaintDest(&dst);
+ albumart.stretchToRectAlpha(canvas, &dst, getPaintingAlpha());
+ }
+ return 1;
+}
+*/
+int AlbumArt::setXuiParam( int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval )
+{
+ if ( xuihandle != _xuihandle )
+ return ALBUMART_PARENT::setXuiParam( _xuihandle, attrid, name, strval );
+
+ switch ( attrid )
+ {
+ case ALBUMART_NOTFOUNDIMAGE:
+ missing_art_image = strval;
+ if ( !bits )
+ {
+ noMakiCallback = true;
+ ArtLoaded( 0, 0, 0 );
+ noMakiCallback = false;
+ }
+ break;
+ case ALBUMART_SOURCE:
+ src_file = strval;
+ AlbumArt::corecb_onUrlChange( wa2.GetCurrentFile() ); // This Param should _always_ hold our current file
+ break;
+ case ALBUMART_VALIGN:
+ if ( !WCSICMP( strval, L"top" ) )
+ valign = -1;
+ else if ( !WCSICMP( strval, L"bottom" ) )
+ valign = 1;
+ else
+ valign = 0;
+
+ deferedInvalidate();
+ break;
+ case ALBUMART_ALIGN:
+ if ( !WCSICMP( strval, L"left" ) )
+ align = -1;
+ else if ( !WCSICMP( strval, L"right" ) )
+ align = 1;
+ else
+ align = 0;
+
+ deferedInvalidate();
+ break;
+ case ALBUMART_STRETCHED:
+ if ( !WCSICMP( strval, L"0" ) || !WCSICMP( strval, L"" ) )
+ stretched = false;
+ else
+ stretched = true;
+
+ deferedInvalidate();
+ break;
+ case ALBUMART_NOREFRESH:
+ if ( !WCSICMP( strval, L"0" ) || !WCSICMP( strval, L"" ) )
+ noAutoRefresh = false;
+ else
+ noAutoRefresh = true;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void AlbumArt::metacb_ArtUpdated( const wchar_t *filename )
+{
+ // it'd be nice to do this, but we can't guarantee that our file didn't get updated in the process
+ //const wchar_t *curFn = wa2.GetCurrentFile();
+// if (curFn && filename && *filename && *curFn && !_wcsicmp(filename, curFn))
+ AlbumArt::corecb_onUrlChange( wa2.GetCurrentFile() );
+}
+
+
+scriptVar AlbumArt::script_vcpu_refresh( SCRIPT_FUNCTION_PARAMS, ScriptObject *o )
+{
+ SCRIPT_FUNCTION_INIT;
+ AlbumArt *a = static_cast<AlbumArt *>( o->vcpu_getInterface( albumArtGuid ) );
+ if ( a )
+ {
+ a->forceRefresh = true;
+ a->corecb_onUrlChange( wa2.GetCurrentFile() );
+ a->forceRefresh = false;
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar AlbumArt::script_vcpu_isLoading( SCRIPT_FUNCTION_PARAMS, ScriptObject *o )
+{
+ SCRIPT_FUNCTION_INIT;
+ AlbumArt *a = static_cast<AlbumArt *>( o->vcpu_getInterface( albumArtGuid ) );
+ if ( a )
+ {
+ return MAKE_SCRIPT_BOOLEAN( !!a->isLoading );
+ }
+
+ return MAKE_SCRIPT_BOOLEAN( false );
+}
+
+scriptVar AlbumArt::script_vcpu_onAlbumArtLoaded( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar success )
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1( o, albumartController, success );
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1( o, success );
+} \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/AlbumArt.h b/Src/Plugins/General/gen_ff/AlbumArt.h
new file mode 100644
index 00000000..b0fa2c3f
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/AlbumArt.h
@@ -0,0 +1,115 @@
+#ifndef NULLSOFT_GEN_FF_ALBUMART_H
+#define NULLSOFT_GEN_FF_ALBUMART_H
+#include <api/wnd/wndclass/bufferpaintwnd.h>
+#include <api/skin/widgets/layer.h>
+#include <api/syscb/callbacks/metacb.h>
+//#include <api/syscb/callbacks/corecbi.h>
+
+//#define ALBUMART_PARENT GuiObjectWnd
+//#define ALBUMART_PARENT BufferPaintWnd
+#define ALBUMART_PARENT Layer
+
+// {6DCB05E4-8AC4-48c2-B193-49F0910EF54A}
+static const GUID albumArtGuid =
+{ 0x6dcb05e4, 0x8ac4, 0x48c2, { 0xb1, 0x93, 0x49, 0xf0, 0x91, 0xe, 0xf5, 0x4a } };
+
+
+class AlbumArtScriptController : public LayerScriptController
+{
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return layerController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern AlbumArtScriptController *albumartController;
+
+class AlbumArtThreadContext;
+
+class AlbumArt : public ALBUMART_PARENT,
+ public CoreCallbackI, /* to get song change updates */
+ public MetadataCallbackI /* to find out when album art changes */
+// public SkinCallbackI /* to get color theme changes */
+{
+public:
+ AlbumArt();
+ ~AlbumArt();
+
+protected:
+ void metacb_ArtUpdated(const wchar_t *filename);
+ virtual int corecb_onUrlChange(const wchar_t *filename);
+ virtual int onInit();
+ //virtual int onBufferPaint(BltCanvas *canvas, int w, int h);
+ int setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval);
+ int skincb_onColorThemeChanged(const wchar_t *newcolortheme);
+
+ bool LoadArt(AlbumArtThreadContext *context, HANDLE thread_to_notify);
+ /* Layer */
+ SkinBitmap *getBitmap();
+ bool layer_isInvalid();
+ void onSetVisible(int show);
+/*
+ virtual int getWidth();
+ virtual int getHeight();
+*/
+ /*static */void CreateXMLParameters(int master_handle);
+private:
+ void layer_adjustDest(RECT *r);
+
+ int w,h;
+ int valign; // 0 = center, 1 = bottom, -1 = top
+ int align; // 0 = center, 1 = right, -1 = left
+ bool stretched;
+ bool forceRefresh;
+ bool noAutoRefresh;
+ bool noMakiCallback;
+ volatile int isLoading;
+
+ void ArtLoaded(int _w, int _h, ARGB32 *_bits);
+ StringW src_file;
+ ARGB32 *bits;
+ SkinBitmap *artBitmap;
+ AutoSkinBitmap missing_art_image;
+ volatile LONG iterator;
+ HANDLE thread_semaphore, hMainThread;
+
+ friend class AlbumArtThreadContext;
+private:
+ /* XML Parameters */
+ enum
+ {
+ ALBUMART_NOTFOUNDIMAGE,
+ ALBUMART_SOURCE,
+ ALBUMART_VALIGN,
+ ALBUMART_ALIGN,
+ ALBUMART_STRETCHED,
+ ALBUMART_NOREFRESH
+ };
+ static XMLParamPair params[];
+ int xuihandle;
+
+public:
+ static scriptVar script_vcpu_refresh(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onAlbumArtLoaded(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar success);
+ static scriptVar script_vcpu_isLoading(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
+
+extern const wchar_t albumArtXuiObjectStr[];
+extern char albumArtXuiSvcName[];
+class AlbumArtXuiSvc : public XuiObjectSvc<AlbumArt, albumArtXuiObjectStr, albumArtXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Plugins/General/gen_ff/MediaDownloader.cpp b/Src/Plugins/General/gen_ff/MediaDownloader.cpp
new file mode 100644
index 00000000..70a0f476
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/MediaDownloader.cpp
@@ -0,0 +1,307 @@
+#include "precomp__gen_ff.h"
+#include "main.h"
+#include "../Agave/Language/api_language.h"
+#include "../../..\Components\wac_network\wac_network_http_receiver_api.h"
+#include "../nu/AutoWide.h"
+#include "../nu/AutoChar.h"
+#include "../nu/AutoCharFn.h"
+#include "wa2frontend.h"
+#include "resource.h"
+#include "../nu/ns_wc.h"
+#include "../nu/refcount.h"
+#include "api/skin/widgets/xuidownloadslist.h"
+
+#include <shlobj.h>
+#include <shlwapi.h>
+#include <api/script/objects/systemobj.h>
+
+extern wchar_t *INI_DIR;
+
+static void createDirForFileW(wchar_t *str)
+{
+ wchar_t *p = str;
+ if ((p[0] ==L'\\' || p[0] ==L'/') && (p[1] ==L'\\' || p[1] ==L'/'))
+ {
+ p += 2;
+ while (p && *p && *p !=L'\\' && *p !=L'/') p++;
+ if (!p || !*p) return ;
+ p++;
+ while (p && *p && *p !=L'\\' && *p !=L'/') p++;
+ }
+ else
+ {
+ while (p && *p && *p !=L'\\' && *p !=L'/') p++;
+ }
+
+ while (p && *p)
+ {
+ while (p && *p !=L'\\' && *p !=L'/' && *p) p = CharNextW(p);
+ if (p && *p)
+ {
+ wchar_t lp = *p;
+ *p = 0;
+ CreateDirectoryW(str, NULL);
+ *p++ = lp;
+ }
+ }
+}
+
+static wchar_t* defaultPathToStore()
+{
+ static wchar_t pathToStore[MAX_PATH] = {0};
+ if(FAILED(SHGetFolderPathW(NULL, CSIDL_MYMUSIC, NULL, SHGFP_TYPE_CURRENT, pathToStore)))
+ {
+ if(FAILED(SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, pathToStore)))
+ {
+ lstrcpynW(pathToStore, L"C:\\My Music", MAX_PATH);
+ }
+ }
+ return pathToStore;
+}
+
+static void GetPathToStore(wchar_t path_to_store[MAX_PATH])
+{
+ GetPrivateProfileStringW( L"gen_ml_config", L"extractpath", defaultPathToStore(), path_to_store, MAX_PATH, (const wchar_t *)SendMessageW( plugin.hwndParent, WM_WA_IPC, 0, IPC_GETMLINIFILEW ) );
+}
+
+void Winamp2FrontEnd::getDownloadPath(wchar_t path2store[MAX_PATH])
+{
+ GetPathToStore(path2store);
+}
+
+void Winamp2FrontEnd::setDownloadPath(const wchar_t * path2store)
+{
+ WritePrivateProfileStringA( "gen_ml_config", "extractpath", AutoChar( path2store, CP_UTF8 ), (const char *)SendMessageW( plugin.hwndParent, WM_WA_IPC, 0, IPC_GETMLINIFILE ) );
+}
+
+class DownloadCallback : public Countable<ifc_downloadManagerCallback>
+{
+public:
+ DownloadCallback( const wchar_t *destination_filepath, bool storeInMl = true, bool notifyDownloadsList = true )
+ {
+ WCSCPYN( this->destination_filepath, destination_filepath, MAX_PATH );
+
+ this->storeInMl = storeInMl;
+ this->notifyDownloadsList = notifyDownloadsList;
+ }
+
+
+ void OnFinish( DownloadToken token );
+
+ void OnError( DownloadToken token, int error )
+ {
+ if ( notifyDownloadsList )
+ DownloadsList::onDownloadError( token, error );
+
+ Release();
+ }
+
+ void OnCancel( DownloadToken token )
+ {
+ if ( notifyDownloadsList )
+ DownloadsList::onDownloadCancel( token );
+
+ Release();
+ }
+ void OnTick( DownloadToken token )
+ {
+ if ( notifyDownloadsList )
+ DownloadsList::onDownloadTick( token );
+ }
+
+ const wchar_t *getPreferredFilePath()
+ {
+ return destination_filepath;
+ }
+
+ bool getStoreInML()
+ {
+ return storeInMl;
+ }
+ REFERENCE_COUNT_IMPLEMENTATION;
+
+protected:
+ RECVS_DISPATCH;
+
+private:
+ bool storeInMl;
+ bool notifyDownloadsList;
+ wchar_t destination_filepath[ MAX_PATH ];
+};
+
+// TODO: benski> this is a big hack. we should have a MIME manager in Winamp
+struct
+{
+ const char *mime; const char *ext;
+}
+hack_mimes[] = { {"audio/mpeg", ".mp3"} };
+
+void DownloadCallback::OnFinish(DownloadToken token)
+{
+ api_httpreceiver *http = WAC_API_DOWNLOADMANAGER->GetReceiver(token);
+ if (http)
+ {
+ const char *extension = 0;
+ const char *headers = http->getallheaders();
+ // we're trying to figure out wtf kind of file this is
+
+ if (!extension) // just adding this if to make this easier to re-arrange
+ {
+ // 1) check if there's a content-disposition, it might have an extension
+ const char *content_disposition = http->getheader("content-disposition");
+ if (content_disposition)
+ {
+ const char *content_filename = strstr(content_disposition, "filename=");
+ if (content_filename && *content_filename)
+ {
+ content_filename+=9;
+ extension = PathFindExtensionA(content_filename);
+ }
+ }
+ }
+
+ if (!extension)
+ {
+ // 2) check MIME type for something good
+ const char *content_type = http->getheader("content-type");
+ if (content_type)
+ {
+ for (int i=0;i!=sizeof(hack_mimes)/sizeof(hack_mimes[0]);i++)
+ {
+ if (!strcmp(hack_mimes[i].mime, content_type))
+ {
+ extension=hack_mimes[i].ext;
+ }
+ }
+ }
+ }
+
+ const char *url = http->get_url();
+ if (!extension)
+ {
+ // 3) check if URL has an extension
+
+ if (url) // umm, we better have a URL :) but worth a check
+ {
+ extension = PathFindExtensionA(url);
+ }
+ }
+
+ if (!extension)
+ {
+ // 4) ask for winamp's default extension and use that (most likely mp3)
+ extension=".mp3"; // TODO: actually use the setting and not hardcode this :)
+ }
+
+ // then we rename the file
+ wchar_t temppath[MAX_PATH-14] = {0};
+ wchar_t filename[MAX_PATH] = {0};
+
+ GetTempPathW(MAX_PATH-14, temppath);
+ GetTempFileNameW(temppath, L"atf", 0, filename);
+ PathRemoveExtensionW(filename);
+ PathAddExtensionW(filename, AutoWide(extension));
+
+ const wchar_t *downloadDest = WAC_API_DOWNLOADMANAGER->GetLocation(token);
+ MoveFileW(downloadDest, filename);
+
+ // then we build a filename with ATF
+ wchar_t formatted_filename[MAX_PATH] = {0}, path_to_store[MAX_PATH] = {0};
+ if (!WCSICMP(this->getPreferredFilePath(), L""))
+ GetPathToStore(path_to_store);
+ else
+ WCSCPYN(path_to_store, this->getPreferredFilePath(), MAX_PATH);
+
+ // TODO: benski> this is very temporary
+ char temp_filename[MAX_PATH] = {0}, *t = temp_filename,
+ *tfn = PathFindFileNameA(url);
+
+ while(tfn && *tfn)
+ {
+ if(*tfn == '%')
+ {
+ if(_strnicmp(tfn,"%20",3))
+ {
+ *t = *tfn;
+ }
+ else{
+ *t = ' ';
+ tfn = CharNextA(tfn);
+ tfn = CharNextA(tfn);
+ }
+ }
+ else
+ {
+ *t = *tfn;
+ }
+ tfn = CharNextA(tfn);
+ t = CharNextA(t);
+ }
+
+ *t = 0;
+
+ PathCombineW(formatted_filename, path_to_store, AutoWide(temp_filename));
+ createDirForFileW(formatted_filename);
+
+ // then move the file there
+ if (!MoveFileW(filename, formatted_filename))
+ {
+ CopyFileW(filename, formatted_filename, FALSE);
+ DeleteFileW(filename);
+ }
+
+ //Std::messageBox(formatted_filename, filename, 0);
+ if (this->getStoreInML() && PathFileExistsW(formatted_filename))
+ {
+ // then add to the media library :)
+ // TOOD: benski> use api_mldb because it's more thread-friendly than SendMessageW
+ HWND library = wa2.getMediaLibrary();
+ LMDB_FILE_ADD_INFOW fi = {const_cast<wchar_t *>(formatted_filename), -1, -1};
+ SendMessageW(library, WM_ML_IPC, (WPARAM)&fi, ML_IPC_DB_ADDORUPDATEFILEW);
+ PostMessage(library, WM_ML_IPC, 0, ML_IPC_DB_SYNCDB);
+ }
+
+ if (notifyDownloadsList)
+ DownloadsList::onDownloadEnd(token, const_cast<wchar_t *>(formatted_filename));
+
+ SystemObject::onDownloadFinished(AutoWide(url), true, formatted_filename);
+
+ Release();
+
+ return;
+ }
+
+ if (notifyDownloadsList)
+ DownloadsList::onDownloadEnd(token, NULL);
+
+ Release();
+}
+
+int Winamp2FrontEnd::DownloadFile( const char *url, const wchar_t *destfilepath, bool addToMl, bool notifyDownloadsList )
+{
+ DownloadCallback *callback = new DownloadCallback( destfilepath, addToMl, notifyDownloadsList );
+ DownloadToken dt = WAC_API_DOWNLOADMANAGER->Download( url, callback );
+
+ // Notify <DownloadsList/>
+ if ( notifyDownloadsList )
+ DownloadsList::onDownloadStart( url, dt );
+
+ return 0;
+ /*
+ HTTPRETRIEVEFILEW func = (HTTPRETRIEVEFILEW) SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GETHTTPGETTERW);
+ if (func || func == (HTTPRETRIEVEFILEW)1)
+ return func(NULL, url, destfilename, title);
+ else
+ return 0;
+ */
+}
+
+#define CBCLASS DownloadCallback
+START_DISPATCH;
+REFERENCE_COUNTED;
+VCB( IFC_DOWNLOADMANAGERCALLBACK_ONFINISH, OnFinish )
+VCB( IFC_DOWNLOADMANAGERCALLBACK_ONTICK, OnTick )
+VCB( IFC_DOWNLOADMANAGERCALLBACK_ONERROR, OnError )
+VCB( IFC_DOWNLOADMANAGERCALLBACK_ONCANCEL, OnCancel )
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Plugins/General/gen_ff/README.txt b/Src/Plugins/General/gen_ff/README.txt
new file mode 100644
index 00000000..80adc9f8
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/README.txt
@@ -0,0 +1,6 @@
+- unzip skindirectory.zip into your Winamp2 Skins directory. for now, gen_ff will manually load an
+ unzipped mmd3.
+- unzip plugindirectory in the ... wa2 plugin directory :) these are the xml and png files for default
+ objects look, skins rely on that for fallback, it's also where we put the new art if we need
+ any (ie static bucketitems will go there eventually instead of being resources)
+
diff --git a/Src/Plugins/General/gen_ff/WinampConfigScriptObject.cpp b/Src/Plugins/General/gen_ff/WinampConfigScriptObject.cpp
new file mode 100644
index 00000000..ae1a7ef0
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/WinampConfigScriptObject.cpp
@@ -0,0 +1,276 @@
+#include <precomp.h>
+#include "WinampConfigScriptObject.h"
+
+// {B2AD3F2B-31ED-4e31-BC6D-E9951CD555BB}
+static const GUID winampConfigScriptGuid =
+{ 0xb2ad3f2b, 0x31ed, 0x4e31, { 0xbc, 0x6d, 0xe9, 0x95, 0x1c, 0xd5, 0x55, 0xbb } };
+
+// {FC17844E-C72B-4518-A068-A8F930A5BA80}
+static const GUID winampConfigGroupScriptGuid =
+{ 0xfc17844e, 0xc72b, 0x4518, { 0xa0, 0x68, 0xa8, 0xf9, 0x30, 0xa5, 0xba, 0x80 } };
+
+static WinampConfigScriptController _winampConfigController;
+ScriptObjectController *winampConfigController = &_winampConfigController;
+
+static WinampConfigGroupScriptController _winampConfigGroupController;
+ScriptObjectController *winampConfigGroupController = &_winampConfigGroupController;
+
+BEGIN_SERVICES(WinampConfig_svcs);
+DECLARE_SERVICETSINGLE(svc_scriptObject, WinampConfigScriptObjectSvc);
+END_SERVICES(WinampConfig_svcs, _WinampConfig_svcs);
+
+#ifdef _X86_
+extern "C"
+{
+ int _link_WinampConfig_svcs;
+}
+#else
+extern "C"
+{
+ int __link_WinampConfig_svcs;
+}
+#endif
+// -----------------------------------------------------------------------------------------------------
+// Service
+
+ScriptObjectController *WinampConfigScriptObjectSvc::getController(int n)
+{
+ switch (n)
+ {
+ case 0:
+ return winampConfigController;
+ case 1:
+ return winampConfigGroupController;
+ }
+ return NULL;
+}
+
+// -- Functions table -------------------------------------
+function_descriptor_struct WinampConfigScriptController::exportedFunction[] =
+{
+ {L"getGroup", 1, (void*)WinampConfig::script_vcpu_getGroup },
+};
+
+// --------------------------------------------------------
+
+const wchar_t *WinampConfigScriptController::getClassName()
+{
+ return L"WinampConfig";
+}
+
+const wchar_t *WinampConfigScriptController::getAncestorClassName()
+{
+ return L"Object";
+}
+
+ScriptObject *WinampConfigScriptController::instantiate()
+{
+ WinampConfig *wc = new WinampConfig;
+ ASSERT(wc != NULL);
+ return wc->getScriptObject();
+}
+
+void WinampConfigScriptController::destroy(ScriptObject *o)
+{
+ WinampConfig *wc = static_cast<WinampConfig *>(o->vcpu_getInterface(winampConfigScriptGuid));
+ if (wc)
+ delete wc;
+}
+
+void *WinampConfigScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation yet
+}
+
+void WinampConfigScriptController::deencapsulate(void *o)
+{
+}
+
+int WinampConfigScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *WinampConfigScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID WinampConfigScriptController::getClassGuid()
+{
+ return winampConfigScriptGuid;
+}
+
+/* ------------- */
+
+WinampConfig::WinampConfig()
+{
+ getScriptObject()->vcpu_setInterface(winampConfigScriptGuid, (void *)static_cast<WinampConfig *>(this));
+ getScriptObject()->vcpu_setClassName(L"WinampConfig");
+ getScriptObject()->vcpu_setController(winampConfigController);
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(Agave::AgaveConfigGUID);
+ if (sf)
+ config = (Agave::api_config *)sf->getInterface();
+}
+
+WinampConfig::~WinampConfig()
+{
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(Agave::AgaveConfigGUID);
+ if (sf)
+ sf->releaseInterface(config);
+}
+
+scriptVar WinampConfig::script_vcpu_getGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar groupguid)
+{
+ SCRIPT_FUNCTION_INIT
+
+ const wchar_t *g = GET_SCRIPT_STRING(groupguid);
+ GUID _g = nsGUID::fromCharW(g);
+
+ WinampConfig *wc = static_cast<WinampConfig *>(o->vcpu_getInterface(winampConfigScriptGuid));
+ if (wc)
+ {
+ Agave::ifc_configgroup *group = wc->config->GetGroup(_g);
+ if (group)
+ {
+ WinampConfigGroup *winampConfigGroup = new WinampConfigGroup(group);
+ return MAKE_SCRIPT_OBJECT(winampConfigGroup->getScriptObject());
+ }
+ }
+ RETURN_SCRIPT_NULL;
+}
+
+/* ------------- */
+
+// -- Functions table -------------------------------------
+function_descriptor_struct WinampConfigGroupScriptController::exportedFunction[] =
+{
+ {L"getBool", 1, (void*)WinampConfigGroup::script_vcpu_getBool },
+ {L"getString", 1, (void*)WinampConfigGroup::script_vcpu_getString },
+ {L"getInt", 1, (void*)WinampConfigGroup::script_vcpu_getInt },
+ {L"setBool", 2, (void*)WinampConfigGroup::script_vcpu_setBool },
+};
+// --------------------------------------------------------
+
+const wchar_t *WinampConfigGroupScriptController::getClassName()
+{
+ return L"WinampConfigGroup";
+}
+
+const wchar_t *WinampConfigGroupScriptController::getAncestorClassName()
+{
+ return L"Object";
+}
+
+ScriptObject *WinampConfigGroupScriptController::instantiate()
+{
+ WinampConfigGroup *wc = new WinampConfigGroup;
+ ASSERT(wc != NULL);
+ return wc->getScriptObject();
+}
+
+void WinampConfigGroupScriptController::destroy(ScriptObject *o)
+{
+ WinampConfigGroup *wc = static_cast<WinampConfigGroup *>(o->vcpu_getInterface(winampConfigGroupScriptGuid));
+ if (wc)
+ delete wc;
+}
+
+void *WinampConfigGroupScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation yet
+}
+
+void WinampConfigGroupScriptController::deencapsulate(void *o)
+{
+}
+
+int WinampConfigGroupScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *WinampConfigGroupScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID WinampConfigGroupScriptController::getClassGuid()
+{
+ return winampConfigGroupScriptGuid;
+}
+
+/* ------------- */
+
+WinampConfigGroup::WinampConfigGroup()
+{
+getScriptObject()->vcpu_setInterface(winampConfigGroupScriptGuid, (void *)static_cast<WinampConfigGroup *>(this));
+ getScriptObject()->vcpu_setClassName(L"WinampConfigGroup");
+ getScriptObject()->vcpu_setController(winampConfigGroupController);
+ configGroup = 0;
+}
+
+WinampConfigGroup::WinampConfigGroup(Agave::ifc_configgroup *_configGroup)
+{
+ getScriptObject()->vcpu_setInterface(winampConfigGroupScriptGuid, (void *)static_cast<WinampConfigGroup *>(this));
+ getScriptObject()->vcpu_setClassName(L"WinampConfigGroup");
+ getScriptObject()->vcpu_setController(winampConfigGroupController);
+ configGroup = _configGroup;
+}
+
+Agave::ifc_configitem *WinampConfigGroup::GetItem(ScriptObject *o, scriptVar itemname)
+{
+ const wchar_t *item = GET_SCRIPT_STRING(itemname);
+ WinampConfigGroup *group = static_cast<WinampConfigGroup *>(o->vcpu_getInterface(winampConfigGroupScriptGuid));
+ if (group)
+ {
+ Agave::ifc_configitem *configitem = group->configGroup->GetItem(item);
+ return configitem;
+ }
+ return 0;
+}
+
+scriptVar WinampConfigGroup::script_vcpu_getBool(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar itemname)
+{
+ SCRIPT_FUNCTION_INIT
+ Agave::ifc_configitem *configitem = GetItem(o, itemname);
+ if (configitem)
+ return MAKE_SCRIPT_BOOLEAN(configitem->GetBool());
+
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar WinampConfigGroup::script_vcpu_getString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar itemname)
+{
+ SCRIPT_FUNCTION_INIT
+ Agave::ifc_configitem *configitem = GetItem(o, itemname);
+ if (configitem)
+ return MAKE_SCRIPT_STRING(configitem->GetString());
+
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar WinampConfigGroup::script_vcpu_getInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar itemname)
+{
+ SCRIPT_FUNCTION_INIT
+ Agave::ifc_configitem *configitem = GetItem(o, itemname);
+ if (configitem)
+ return MAKE_SCRIPT_INT(configitem->GetInt());
+
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar WinampConfigGroup::script_vcpu_setBool(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar itemname, scriptVar value)
+{
+ SCRIPT_FUNCTION_INIT
+ const wchar_t *item = GET_SCRIPT_STRING(itemname);
+ WinampConfigGroup *group = static_cast<WinampConfigGroup *>(o->vcpu_getInterface(winampConfigGroupScriptGuid));
+ if (group)
+ {
+ Agave::ifc_configitem *configitem = group->configGroup->GetItem(item);
+ if (configitem)
+ configitem->SetBool(!!GET_SCRIPT_BOOLEAN(value));
+ }
+ RETURN_SCRIPT_VOID;
+} \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/WinampConfigScriptObject.h b/Src/Plugins/General/gen_ff/WinampConfigScriptObject.h
new file mode 100644
index 00000000..12cff269
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/WinampConfigScriptObject.h
@@ -0,0 +1,99 @@
+#ifndef NULLSOFT_GEN_FF_WINAMPCONFIGSCRIPTOBJECT_H
+#define NULLSOFT_GEN_FF_WINAMPCONFIGSCRIPTOBJECT_H
+
+#include <api/script/objects/rootobj.h>
+#include <api/script/script.h>
+#include <api/script/objects/rootobject.h>
+#include <api/service/svcs/svc_scriptobji.h>
+namespace Agave
+{
+ #include "../Agave/Config/api_config.h"
+}
+
+// -----------------------------------------------------------------------------------------------------
+// ScriptObject Service
+class WinampConfigScriptObjectSvc : public svc_scriptObjectI
+{
+public:
+ WinampConfigScriptObjectSvc() {};
+ virtual ~WinampConfigScriptObjectSvc() {};
+
+ static const char *getServiceName() { return "Winamp Config script object"; }
+ virtual ScriptObjectController *getController(int n);
+};
+
+class WinampConfigScriptController : public ScriptObjectControllerI
+{
+ public:
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return rootScriptObjectController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+};
+
+extern ScriptObjectController *winampConfigController;
+extern ScriptObjectController *winampConfigGroupController;
+
+#define WINAMPCONFIG_PARENT RootObjectInstance
+
+class WinampConfig : public WINAMPCONFIG_PARENT
+{
+public:
+ WinampConfig();
+ ~WinampConfig();
+public:
+ virtual const wchar_t *vcpu_getClassName() { return L"WinampConfig"; }
+ virtual ScriptObjectController *vcpu_getController() { return winampConfigController; }
+
+ static scriptVar script_vcpu_getGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+
+ Agave::api_config *config;
+};
+
+class WinampConfigGroupScriptController : public ScriptObjectControllerI {
+ public:
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return rootScriptObjectController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+};
+
+#define WINAMPCONFIGGROUP_PARENT RootObjectInstance
+class WinampConfigGroup : public WINAMPCONFIGGROUP_PARENT
+{
+public:
+ WinampConfigGroup();
+ WinampConfigGroup(Agave::ifc_configgroup *_configGroup);
+
+public:
+ virtual const wchar_t *vcpu_getClassName() { return L"WinampConfigGroup"; }
+ virtual ScriptObjectController *vcpu_getController() { return winampConfigGroupController; }
+
+ static Agave::ifc_configitem *GetItem(ScriptObject *o, scriptVar n); // helper function
+ static scriptVar script_vcpu_getBool(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+ static scriptVar script_vcpu_getString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+ static scriptVar script_vcpu_getInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+ static scriptVar script_vcpu_setBool(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar itemname, scriptVar value);
+
+ Agave::ifc_configgroup *configGroup;
+};
+
+#endif
diff --git a/Src/Plugins/General/gen_ff/api__gen_ff.h b/Src/Plugins/General/gen_ff/api__gen_ff.h
new file mode 100644
index 00000000..f011e918
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/api__gen_ff.h
@@ -0,0 +1,20 @@
+#ifndef NULLSOFT_GEN_FF_API_H
+#define NULLSOFT_GEN_FF_API_H
+
+#include <api/memmgr/api_memmgr.h>
+extern api_memmgr *memmgrApi;
+#define WASABI_API_MEMMGR memmgrApi
+
+#include <api/skin/api_colorthemes.h>
+#define WASABI_API_COLORTHEMES colorThemesApi
+
+#include <api/skin/api_palette.h>
+extern api_palette *paletteManagerApi;
+#define WASABI_API_PALETTE paletteManagerApi
+
+#include "../nu/threadpool/api_threadpool.h"
+extern api_threadpool *threadPoolApi;
+#define WASABI_API_THREADPOOL threadPoolApi
+
+
+#endif // !NULLSOFT_GEN_FF_API_H
diff --git a/Src/Plugins/General/gen_ff/bitmaps/library-hilited.png b/Src/Plugins/General/gen_ff/bitmaps/library-hilited.png
new file mode 100644
index 00000000..7abf190f
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/library-hilited.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/library-selected.png b/Src/Plugins/General/gen_ff/bitmaps/library-selected.png
new file mode 100644
index 00000000..904639f1
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/library-selected.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/library-unselected.png b/Src/Plugins/General/gen_ff/bitmaps/library-unselected.png
new file mode 100644
index 00000000..a2a3d7a9
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/library-unselected.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/mb-hilited.png b/Src/Plugins/General/gen_ff/bitmaps/mb-hilited.png
new file mode 100644
index 00000000..2128096c
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/mb-hilited.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/mb-selected.png b/Src/Plugins/General/gen_ff/bitmaps/mb-selected.png
new file mode 100644
index 00000000..f05591d5
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/mb-selected.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/mb-unselected.png b/Src/Plugins/General/gen_ff/bitmaps/mb-unselected.png
new file mode 100644
index 00000000..63338214
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/mb-unselected.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/pledit-hover.png b/Src/Plugins/General/gen_ff/bitmaps/pledit-hover.png
new file mode 100644
index 00000000..c4c7c5e9
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/pledit-hover.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/pledit-selected.png b/Src/Plugins/General/gen_ff/bitmaps/pledit-selected.png
new file mode 100644
index 00000000..3438a11e
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/pledit-selected.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/pledit-unselected.png b/Src/Plugins/General/gen_ff/bitmaps/pledit-unselected.png
new file mode 100644
index 00000000..b6293781
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/pledit-unselected.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/video-hilited.png b/Src/Plugins/General/gen_ff/bitmaps/video-hilited.png
new file mode 100644
index 00000000..4176634a
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/video-hilited.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/video-selected.png b/Src/Plugins/General/gen_ff/bitmaps/video-selected.png
new file mode 100644
index 00000000..15a6027d
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/video-selected.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/video-unselected.png b/Src/Plugins/General/gen_ff/bitmaps/video-unselected.png
new file mode 100644
index 00000000..fa58bedf
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/video-unselected.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/vis-hilited.png b/Src/Plugins/General/gen_ff/bitmaps/vis-hilited.png
new file mode 100644
index 00000000..f9ac424c
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/vis-hilited.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/vis-selected.png b/Src/Plugins/General/gen_ff/bitmaps/vis-selected.png
new file mode 100644
index 00000000..5d478429
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/vis-selected.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/bitmaps/vis-unselected.png b/Src/Plugins/General/gen_ff/bitmaps/vis-unselected.png
new file mode 100644
index 00000000..b0074200
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/bitmaps/vis-unselected.png
Binary files differ
diff --git a/Src/Plugins/General/gen_ff/embedwndguid.cpp b/Src/Plugins/General/gen_ff/embedwndguid.cpp
new file mode 100644
index 00000000..db12ad13
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/embedwndguid.cpp
@@ -0,0 +1,200 @@
+#include "precomp__gen_ff.h"
+#include "embedwndguid.h"
+#include "wa2wndembed.h"
+#include "wa2frontend.h"
+#include "wa2cfgitems.h"
+#include <bfc/string/stringW.h>
+
+extern void initFFApi();
+
+EmbedWndGuidMgr embedWndGuidMgr;
+
+EmbedWndGuid::EmbedWndGuid(embedWindowState *_ws)
+{
+ hwnd = NULL;
+ guid = INVALID_GUID;
+ if (_ws == NULL) return ;
+
+ ws = _ws;
+ hwnd = ws->me;
+ embedWndGuidMgr.getGuid(this);
+}
+
+EmbedWndGuid::EmbedWndGuid(EmbedWndGuid *wg)
+{
+ hwnd = NULL;
+ guid = INVALID_GUID;
+ if (wg == NULL) return ;
+
+ ws = wg->getEmbedWindowState();
+ hwnd = ws->me;
+ guid = wg->getGuid();
+}
+
+GUID EmbedWndGuidMgr::getGuid(embedWindowState *ws)
+{
+ foreach(table)
+ EmbedWndGuid *ewg = table.getfor();
+ if (ewg->getEmbedWindowState() == ws)
+ {
+ return ewg->getGuid();
+ }
+ endfor;
+ return INVALID_GUID;
+}
+
+GUID EmbedWndGuidMgr::getGuid(EmbedWndGuid *wg)
+{
+ if (wg == NULL) return INVALID_GUID;
+ // if we aren't loaded yet, init wasabi, otherwise ignore
+ initFFApi();
+
+ int gotit = 0;
+ int nowrite = 0;
+ wchar_t windowTitle[256] = L"";
+ HWND child;
+
+ GUID newGuid = INVALID_GUID;
+
+ if (wg->getEmbedWindowState()->flags & EMBED_FLAGS_GUID)
+ {
+ newGuid = GET_EMBED_GUID(wg->getEmbedWindowState());
+ nowrite=1;
+ goto bypass;
+ }
+
+ if (wa2.isVis(wg->getEmbedWindowState()->me))
+ {
+ newGuid = avs_guid;
+ nowrite = 1;
+ extern int disable_send_visrandom;
+ extern _bool visrandom;
+ wa2.pollVisRandom();
+ goto bypass;
+ }
+
+ child = GetWindow(wg->getEmbedWindowState()->me, GW_CHILD);
+ if (child == wa2.getMediaLibrary())
+ { newGuid = library_guid; nowrite = 1; goto bypass; }
+
+ if (!gotit)
+ {
+ foreach(table)
+ EmbedWndGuid *ewg = table.getfor();
+ if (ewg->getEmbedWindowState() == wg->getEmbedWindowState())
+ {
+ wg->setGuid(ewg->getGuid());
+ gotit = 1;
+ break;
+ }
+ endfor;
+ }
+
+ if (!gotit)
+ {
+ // not found, look for window title in saved table
+ GetWindowTextW(wg->getEmbedWindowState()->me, windowTitle, 256);
+ if (*windowTitle)
+ {
+ wchar_t str[256] = L"";
+ StringW configString = windowTitle;
+ configString += L"_guid";
+ WASABI_API_CONFIG->getStringPrivate(configString, str, 256, L"");
+ if (*str)
+ {
+ wg->setGuid(nsGUID::fromCharW(str));
+ table.addItem(new EmbedWndGuid(wg));
+ gotit = 1;
+ }
+ }
+ }
+
+ if (!gotit)
+ {
+ // not found in saved table, or no title for the window, assign a new guid
+ if (!_wcsicmp(windowTitle, L"AVS"))
+ { newGuid = avs_guid; nowrite = 1; }
+ else
+ CoCreateGuid(&newGuid);
+
+ bypass:
+
+ wg->setGuid(newGuid);
+
+ // save a copy of the element
+ table.addItem(new EmbedWndGuid(wg));
+
+ // write the guid in the saved table
+ if (*windowTitle && !nowrite)
+ {
+ wchar_t str[256] = {0};
+ nsGUID::toCharW(newGuid, str);
+ StringW configString = windowTitle;
+ configString += L"_guid";
+ WASABI_API_CONFIG->setStringPrivate(configString, str);
+ }
+ }
+ return wg->getGuid();
+}
+
+embedWindowState *EmbedWndGuidMgr::getEmbedWindowState(GUID g)
+{
+ foreach(table)
+ EmbedWndGuid *ewg = table.getfor();
+ if (ewg->getGuid() == g)
+ {
+ embedWindowState *ews = ewg->getEmbedWindowState();
+ if (wa2.isValidEmbedWndState(ews))
+ return ews;
+ }
+ endfor;
+ return NULL;
+}
+
+void EmbedWndGuidMgr::retireEmbedWindowState(embedWindowState *ws)
+{
+ foreach(table)
+ EmbedWndGuid *ewg = table.getfor();
+ if (ewg->getEmbedWindowState() == ws)
+ {
+ delete table.getfor();
+ table.removeByPos(foreach_index);
+ break;
+ }
+ endfor;
+}
+
+int EmbedWndGuidMgr::testGuid(GUID g)
+{
+ // if (g == library_guid) return 1;
+ // if (g == avs_guid) return 1;
+ foreach(table)
+ EmbedWndGuid *ewg = table.getfor();
+ if (ewg->getGuid() == g)
+ {
+ if (!wa2.isValidEmbedWndState(ewg->getEmbedWindowState())) retireEmbedWindowState(ewg->getEmbedWindowState());
+ else return 1;
+ }
+ endfor;
+ return 0;
+}
+
+int EmbedWndGuidMgr::getNumWindowStates()
+{
+ return table.getNumItems();
+}
+
+GUID EmbedWndGuidMgr::enumWindowState(int n, embedWindowState **ws)
+{
+ EmbedWndGuid *ewg = table.enumItem(n);
+ if (ewg)
+ {
+ embedWindowState *ews = ewg->getEmbedWindowState();
+ if (wa2.isValidEmbedWndState(ews))
+ {
+ if (ws) *ws = ews;
+ return ewg->getGuid();
+ }
+ }
+ return INVALID_GUID;
+} \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/embedwndguid.h b/Src/Plugins/General/gen_ff/embedwndguid.h
new file mode 100644
index 00000000..8e9e39e7
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/embedwndguid.h
@@ -0,0 +1,42 @@
+#ifndef _EMBEDWNDGUID_H
+#define _EMBEDWNDGUID_H
+
+#include "../winamp/wa_ipc.h"
+
+class EmbedWndGuid
+{
+ public:
+ EmbedWndGuid(EmbedWndGuid *wg);
+ EmbedWndGuid(embedWindowState *ws);
+ GUID getGuid() { return guid; }
+ embedWindowState *getEmbedWindowState() { return ws; }
+ void setGuid(GUID g) { guid = g; }
+ HWND getHWND() { return hwnd; }
+ void setHWND(HWND w) { hwnd = w; }
+
+
+ private:
+ GUID guid;
+ embedWindowState *ws;
+ HWND hwnd;
+};
+
+class EmbedWndGuidMgr
+{
+ public:
+ GUID getGuid(EmbedWndGuid *wg);
+ GUID getGuid(embedWindowState *ws);
+ embedWindowState *getEmbedWindowState(GUID g);
+ int testGuid(GUID g);
+ void retireEmbedWindowState(embedWindowState *ws);
+ int getNumWindowStates();
+ GUID enumWindowState(int n, embedWindowState **ws=NULL);
+
+ private:
+ PtrList<EmbedWndGuid> table;
+
+};
+
+extern EmbedWndGuidMgr embedWndGuidMgr;
+
+#endif // _EMBEDWNDGUID_H \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/ff_ipc.cpp b/Src/Plugins/General/gen_ff/ff_ipc.cpp
new file mode 100644
index 00000000..12d0325f
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/ff_ipc.cpp
@@ -0,0 +1,535 @@
+#include "precomp__gen_ff.h"
+#include "gen_ff_ipc.h"
+#include "ff_ipc.h"
+#include "../winamp/wa_ipc.h"
+#include "wa2frontend.h"
+#include <tataki/color/skinclr.h>
+#include <api/wnd/wndclass/buttwnd.h>
+#include <api/wndmgr/skinwnd.h>
+#include <tataki/blending/blending.h>
+#include <api/skin/skinparse.h>
+#include <api/wnd/wndtrack.h>
+#include "wa2wndembed.h"
+#include "embedwndguid.h"
+#include <tataki/canvas/bltcanvas.h>
+#include "../nu/AutoChar.h"
+#include "../nu/AutoWide.h"
+ColorThemeMonitor *colorThemeMonitor = NULL;
+
+HBITMAP CreateBitmapDIB(int w, int h, int planes, int bpp, void *data)
+{
+#if 0
+ return CreateBitmap(w, h, planes, bpp, data);
+#else
+ void *bits=0;
+ BITMAPINFO bmi={0,};
+ bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = bpp;
+ bmi.bmiHeader.biSizeImage = w*h*(bpp/8);
+ bmi.bmiHeader.biCompression=BI_RGB;
+
+ HBITMAP bm=CreateDIBSection(0,&bmi,0,&bits,NULL,0);
+
+ if (bm && bits) memcpy(bits,data,w*h*(bpp/8));
+ return bm;
+#endif
+}
+
+HWND ff_ipc_getContentWnd(HWND w) {
+ HWND ret = w;
+
+ ifc_window *wnd = windowTracker->rootWndFromHwnd(w); // TODO: API_WNDMGR->
+ if (wnd) {
+ ifc_window *dp = wnd->getDesktopParent();
+ if (dp) {
+ Layout *l = static_cast<Layout *>(dp->getInterface(layoutGuid));
+ if (l) {
+ Container *c = l->getParentContainer();
+ if (c) {
+ GUID g = c->getDefaultContent();
+ if (g != INVALID_GUID) {
+ if (g == playerWndGuid)
+ ret = wa2.getMainWindow();
+ else if (g == pleditWndGuid)
+ ret = wa2.getWnd(IPC_GETWND_PE);
+ else if (g == videoWndGuid)
+ ret = wa2.getWnd(IPC_GETWND_VIDEO);
+ else {
+ embedWindowState *ews = embedWndGuidMgr.getEmbedWindowState(g);
+ if (ews)
+ ret = ews->me;
+ }
+ }
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+
+void ff_ipc_getSkinColor(ff_skincolor *cs)
+{
+ if (cs == NULL) return;
+ cs->color = RGBTOBGR(SkinColor(AutoWide(cs->colorname)));
+}
+#define USE_WIN32_ALPHABLEND
+static void ButtonSetup(ButtonWnd &_w)
+{
+ _w.setVirtual(0);
+ _w.setStartHidden(1);
+ _w.setParent(WASABI_API_WND->main_getRootWnd());
+ _w.init(WASABI_API_WND->main_getRootWnd());
+ _w.setCloaked(1);
+ _w.setVisible(1);
+}
+
+static void DoButtonBlit(ButtonWnd &_w, int w, int h, int state, const wchar_t *overlayelement, int xpos, int ypos, BltCanvas *c)
+{
+ if (state == BUTTONSTATE_PUSHED) _w.setPushed(1);
+ else _w.setPushed(0);
+ _w.resize(0, 0, w, h);
+ _w.deferedInvalidate();
+ _w.paint(NULL, NULL);
+ Canvas *cv = NULL;
+ cv = _w.getFrameBuffer();
+ if (cv != NULL) {
+ BltCanvas *bltcanvas = static_cast<BltCanvas *>(cv); // hackish
+#ifdef USE_WIN32_ALPHABLEND
+ bltcanvas->/*getSkinBitmap()->*/blitAlpha(c, xpos, ypos);
+#else
+ bltcanvas->getSkinBitmap()->blitAlpha(c, xpos, ypos);
+#endif
+ }
+ if (overlayelement && *overlayelement) {
+ AutoSkinBitmap b(overlayelement);
+ SkinBitmap *sb = b.getBitmap();
+ int shift = (state == BUTTONSTATE_PUSHED) ? 1 : 0;
+ sb->blitAlpha(c, xpos+(w-sb->getWidth())/2+shift, ypos+(h-sb->getHeight())/2+shift);
+ }
+}
+
+void blitButtonToCanvas(int w, int h, int state, const wchar_t *overlayelement, int xpos, int ypos, BltCanvas *c)
+{
+ ButtonWnd _w;
+ ButtonSetup(_w);
+ DoButtonBlit(_w, w, h, state, overlayelement, xpos, ypos, c);
+
+}
+
+static HBITMAP generateButtonBitmap(int w, int h, int state, const wchar_t *overlayelement=NULL) {
+ BltCanvas c(w, h);
+ blitButtonToCanvas(w,h,state,overlayelement,0,0,&c);
+ SysCanvas cc;
+ c.blit(0, 0, &cc, 0, 0, w, h);
+ return CreateBitmapDIB(w, h, 1, 32, c.getBits());
+}
+
+COLORREF getWindowBackground(COLORREF *wb)
+{
+ static String last_skin, last_theme;
+ static COLORREF last_windowbackground = 0x00000000;
+
+ COLORREF windowbackground = 0x00000000;
+
+ // window background (used to set the bg color for the dialog)
+ if (!WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.window.background"))
+ {
+ String curskin = AutoChar(WASABI_API_SKIN->getSkinName());
+ String curtheme = AutoChar(WASABI_API_SKIN->colortheme_getColorSet());
+ if (!last_skin.iscaseequal(curskin) || !last_theme.iscaseequal(curtheme)) {
+ last_skin = curskin;
+ last_theme = curtheme;
+ // extract the window color from an active piece of skin
+ SkinWnd w(L"$$$.some.purposedly.undefined.group.$$$", NULL, 0, NULL, 1, 1);
+ ifc_window *wnd = w.getWindow();
+ if (wnd != NULL) {
+ ifc_window *wh = wnd->findWindowByInterface(windowHolderGuid);
+ if (wh != NULL) {
+ wnd = wnd->getDesktopParent();
+ if (w.isNewContainer()) {
+ wnd->setCloaked(1);
+ wnd->setVisible(1);
+ wnd->resize(0, 0, 320, 200);
+ wnd->paint();
+ }
+ BltCanvas *canvas = static_cast<BltCanvas *>(wnd->getFrameBuffer());
+ if (!canvas) goto basetexture; // eek :-D
+ int x=0, y=0;
+ RECT r;
+ wh->getClientRect(&r);
+ x = r.left + (r.right-r.left)/2; y = r.top + (r.bottom-r.top)/2;
+ COLORREF *bits = (COLORREF *)canvas->getBits();
+ int w, h;
+ canvas->getDim(&w, &h, NULL);
+ if (w == 0 || h == 0)
+ windowbackground = 0; // black by default
+ else
+ windowbackground = bits[y*w+x];
+ }
+ }
+ w.destroy();
+ if (windowbackground == 0x00000000) {
+ basetexture:
+ // try for wasabi.basetexture ...
+ int _w, _h, _x, _y;
+ ARGB32 *b = WASABI_API_SKIN->imgldr_requestSkinBitmap(L"wasabi.basetexture", NULL, &_x, &_y, NULL, NULL, &_w, &_h, 1);
+ if (b != NULL) {
+ windowbackground = b[_w*_y+_x];
+ WASABI_API_SKIN->imgldr_releaseSkinBitmap(b);
+ } else {
+ // no idea... we'll just set the default windows color
+ windowbackground = GetSysColor(COLOR_WINDOWFRAME);
+ }
+ }
+ last_windowbackground = windowbackground;
+ } else {
+ windowbackground = last_windowbackground;
+ }
+ if (wb) *wb=windowbackground;
+ return windowbackground;
+ } else {
+ COLORREF c = RGBTOBGR(SkinColor(L"wasabi.window.background"));
+ if (wb) *wb = c;
+ return c;
+ }
+}
+
+inline int lumidiff(int a, int b) {
+ int r1 = (a & 0xFF0000) >> 16;
+ int r2 = (b & 0xFF0000) >> 16;
+ int g1 = (a & 0xFF00) >> 8;
+ int g2 = (b & 0xFF00) >> 8;
+ int b1 = a & 0xFF;
+ int b2 = b & 0xFF;
+ return MIN((ABS(r1-r2), ABS(g1-g2)), ABS(b1-b2));
+}
+
+HBITMAP ff_genwa2skinbitmap()
+{
+ int interpolate = 0;
+ if (SkinParser::getSkinVersion()*10 < 10) interpolate = 1;
+
+ BltCanvas c(132, 75);
+ COLORREF windowbackground = 0;
+ COLORREF wbg=getWindowBackground(&windowbackground);
+
+ COLORREF *ptr=(COLORREF *)c.getBits();
+ c.fillBits(wbg);
+
+ // set up bg color for the picky pixel parser heh
+ int x;
+ for (x = 47; x < 132; x ++) ptr[x]=ptr[x+132]=RGB(0,198,255);
+
+ ButtonWnd _w;
+ ButtonSetup(_w);
+
+ DoButtonBlit(_w, 47,15,0,NULL,0,0,&c);
+ DoButtonBlit(_w, 47,15,1,NULL,0,15,&c);
+
+ DoButtonBlit(_w, 14,14,0,L"wasabi.button.label.arrow.up",0,31,&c);
+ DoButtonBlit(_w, 14,14,0,L"wasabi.button.label.arrow.down",14,31,&c);
+ DoButtonBlit(_w, 14,14,1,L"wasabi.button.label.arrow.up",28,31,&c);
+ DoButtonBlit(_w, 14,14,1,L"wasabi.button.label.arrow.down",42,31,&c);
+
+ DoButtonBlit(_w, 14,14,0,L"wasabi.button.label.arrow.left",0,45,&c);
+ DoButtonBlit(_w, 14,14,0,L"wasabi.button.label.arrow.right",14,45,&c);
+ DoButtonBlit(_w, 14,14,1,L"wasabi.button.label.arrow.left",28,45,&c);
+ DoButtonBlit(_w, 14,14,1,L"wasabi.button.label.arrow.right",42,45,&c);
+
+ DoButtonBlit(_w, 14,28,0,L"wasabi.scrollbar.vertical.grip",56,31,&c);
+ DoButtonBlit(_w, 14,28,1,L"wasabi.scrollbar.vertical.grip",70,31,&c);
+
+ DoButtonBlit(_w, 28,14,0,L"wasabi.scrollbar.horizontal.grip",84,31,&c);
+ DoButtonBlit(_w, 28,14,1,L"wasabi.scrollbar.horizontal.grip",84,45,&c);
+
+ // item background (background to edits, listviews etc)
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.background"))
+ ptr[48] = RGBTOBGR(SkinColor(L"wasabi.list.background"));
+ else
+ ptr[48] = WASABI_API_SKIN->skin_getBitmapColor(L"wasabi.list.background"); // RGBTOBGR(SkinColor(L"wasabi.edit.background"));
+
+ COLORREF listbkg = ptr[48];
+
+ // item foreground (text color of edit/listview, etc)
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.text"))
+ ptr[50] = RGBTOBGR(SkinColor(L"wasabi.list.text"));
+ else {
+ int c = RGBTOBGR(SkinColor(L"wasabi.edit.text"));
+ ptr[50] = c;
+ }
+
+ if (interpolate) {
+ int c = ptr[50];
+ c = lumidiff(c, listbkg) < 0x1F ? Blenders::BLEND_AVG(ptr[50], 0xFF7F7F7F) : c;
+ c = lumidiff(c, listbkg) < 0x1F ? Blenders::BLEND_AVG(ptr[50], 0xFF101010) : c;
+ ptr[50] = c | 0xFF000000;
+ }
+
+ ptr[52] = wbg;
+
+ ptr[54] = RGBTOBGR(SkinColor(SKINCOLOR_BUTTON_TEXT));
+
+ // window text color
+ if (!interpolate && WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.window.text"))
+ ptr[56] = RGBTOBGR(SkinColor(L"wasabi.window.text"));
+ else {
+ ptr[56] = RGBTOBGR(SkinColor(SKINCOLOR_LIST_ITEMTEXT)); //"wasabi.textbar.text");//
+ }
+
+
+ // color of dividers and sunken borders
+ if (!interpolate && WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.border.sunken"))
+ ptr[58] = RGBTOBGR(SkinColor(L"wasabi.border.sunken"));
+ else {
+ int a = MAX((windowbackground & 0xFF0000) >> 16, MAX((windowbackground & 0xFF00) >> 8, windowbackground & 0xFF));
+ ptr[58] = Blenders::BLEND_AVG(windowbackground, a > 0xE0 ? 0xFF000000: 0xFFFFFFFF);
+ }
+
+ // listview header background color
+ COLORREF col = RGBTOBGR(SkinColor(SKINCOLOR_LIST_COLUMNBKG));
+ if (interpolate) {
+ int a = MAX((col & 0xFF0000) >> 16, MAX((col & 0xFF00) >> 8, col & 0xFF));
+ col = a < 0x1F ? Blenders::BLEND_AVG(windowbackground, 0xFF000000) : col;
+ }
+ ptr[62] = col;
+
+ // listview header text color
+ ptr[64] = RGBTOBGR(SkinColor(SKINCOLOR_LIST_COLUMNTEXT));
+
+ // listview header frame top color
+ if (!interpolate && WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.column.frame.top"))
+ ptr[66] = RGBTOBGR(SkinColor(L"wasabi.list.column.frame.top"));
+ else
+ ptr[66] = Blenders::BLEND_AVG(col, 0xFFFFFFFF);//listview header frame top color
+
+ // listview header frame middle color
+ if (!interpolate && WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.column.frame.middle"))
+ ptr[68] = RGBTOBGR(SkinColor(L"wasabi.list.column.frame.middle"));
+ else
+ ptr[68] = Blenders::BLEND_AVG(col, 0xFF2F2F2F);
+
+ // listview header frame bottom color
+ if (!interpolate && WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.column.frame.bottom"))
+ ptr[70] = RGBTOBGR(SkinColor(L"wasabi.list.column.frame.bottom"));
+ else
+ ptr[70] = Blenders::BLEND_AVG(col, 0xFF000000);
+
+ // listview header empty color
+ COLORREF empty;
+ if (!interpolate && WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.column.empty"))
+ empty = RGBTOBGR(SkinColor(L"wasabi.list.column.empty"));
+ else
+ empty = Blenders::BLEND_AVG(col, 0xFF000000);
+ ptr[72] = empty;
+
+ // scrollbar foreground color
+ if (!interpolate && WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.scrollbar.foreground"))
+ ptr[74] = RGBTOBGR(SkinColor(L"wasabi.scrollbar.foreground"));
+ else
+ ptr[74] = empty;
+
+ // scrollbar background color
+ if (!interpolate && WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.scrollbar.background"))
+ ptr[76] = RGBTOBGR(SkinColor(L"wasabi.scrollbar.background"));
+ else
+ ptr[76] = empty;
+
+ // inverse scrollbar foreground color
+ if (!interpolate && WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.scrollbar.foreground.inverted"))
+ ptr[78] = RGBTOBGR(SkinColor(L"wasabi.scrollbar.foreground.inverted"));
+ else
+ ptr[78] = col;
+
+ // inverse scrollbar background color
+ if (!interpolate && WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.scrollbar.background.inverted"))
+ ptr[80] = RGBTOBGR(SkinColor(L"wasabi.scrollbar.background.inverted"));
+ else
+ ptr[80] = empty;
+
+ // scrollbar dead area color
+ ptr[82] = windowbackground;
+
+ // listview/treeview selection bar text color
+ COLORREF selfg;
+
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.text.selected"))
+ selfg = RGBTOBGR(SkinColor(L"wasabi.list.text.selected"));
+ else
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.text"))
+ selfg = RGBTOBGR(SkinColor(L"wasabi.list.text"));
+ else
+ selfg = SkinColor(L"wasabi.edit.text");
+
+ ptr[84] = selfg;
+
+
+ // listview/treeview selection bar back color
+ COLORREF selbg;
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.text.selected.background"))
+ selbg = RGBTOBGR(SkinColor(L"wasabi.list.text.selected.background"));
+ else {
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.item.selected"))
+ selbg = RGBTOBGR(SkinColor(L"wasabi.list.item.selected"));
+ else
+ selbg = RGBTOBGR(SkinColor(SKINCOLOR_TREE_SELITEMBKG));
+ selbg = lumidiff(selbg, listbkg) < 0x2F ? Blenders::BLEND_AVG(windowbackground, 0xFF7F7F7F) : selbg;
+ selbg = lumidiff(selbg, listbkg) < 0x2F ? Blenders::BLEND_AVG(listbkg, 0xFF7F7F7F) : selbg;
+ selbg = lumidiff(selbg, listbkg) < 0x2F ? Blenders::BLEND_AVG(windowbackground, 0xFFF0F0F0) : selbg;
+ selbg = lumidiff(selbg, listbkg) < 0x2F ? Blenders::BLEND_AVG(listbkg, 0xFFF0F0F0) : selbg;
+ selbg = lumidiff(selbg, listbkg) < 0x2F ? Blenders::BLEND_AVG(col, 0xFFF0F0F0) : selbg;
+ selbg = lumidiff(selbg, listbkg) < 0x2F ? Blenders::BLEND_AVG(col, 0xFF101010) : selbg;
+ selbg = lumidiff(selbg, selfg) < 0x1F ? Blenders::BLEND_AVG(selbg, 0xFF101010) : selbg;
+ selbg = lumidiff(selbg, selfg) < 0x1F ? Blenders::BLEND_AVG(selbg, 0xFFF0F0F0) : selbg;
+ }
+ ptr[86] = ptr[60] = (selbg | 0xFF000000);
+
+ // listview/treeview selection bar text color (inactive)
+ if (!interpolate && WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.text.selected.inactive"))
+ ptr[88] = RGBTOBGR(SkinColor(L"wasabi.list.text.selected.inactive"));
+ else
+ ptr[88] = selfg;
+
+ // listview/treeview selection bar back color (inactive)
+ if (!interpolate && WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.text.selected.background.inactive"))
+ ptr[90] = RGBTOBGR(SkinColor(L"wasabi.list.text.selected.background.inactive"));
+ else
+ ptr[90] = Blenders::BLEND_ADJ1(selbg, 0xFF000000, 210);
+
+ // alternate item background
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.background.alternate"))
+ ptr[92] = RGBTOBGR(SkinColor(L"wasabi.list.background.alternate"));
+ else
+ ptr[92] = ptr[48];
+
+ // alternate item foreground
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.text.alternate"))
+ {
+ ptr[50] = RGBTOBGR(SkinColor(L"wasabi.list.text.alternate"));
+ if (interpolate) {
+ int c = ptr[94];
+ c = lumidiff(c, listbkg) < 0x1F ? Blenders::BLEND_AVG(ptr[94], 0xFF7F7F7F) : c;
+ c = lumidiff(c, listbkg) < 0x1F ? Blenders::BLEND_AVG(ptr[94], 0xFF101010) : c;
+ ptr[94] = c | 0xFF000000;
+ }
+ }
+ else {
+ ptr[94] = ptr[50];
+ }
+
+ return CreateBitmapDIB(132, 75, 1, 32, c.getBits());
+}
+
+void ff_ipc_genSkinBitmap(ff_skinbitmap *sb) {
+ if (sb == NULL) return;
+ switch (sb->id) {
+ case SKINBITMAP_BUTTON: {
+ HBITMAP bmp = generateButtonBitmap(sb->w, sb->h, sb->state);
+ sb->bitmap = bmp;
+ break;
+ }
+ case SKINBITMAP_SCROLLBARVBUTTON: {
+ HBITMAP bmp = generateButtonBitmap(sb->w, sb->h, sb->state, L"wasabi.scrollbar.vertical.grip");
+ sb->bitmap = bmp;
+ break;
+ }
+ case SKINBITMAP_SCROLLBARHBUTTON: {
+ HBITMAP bmp = generateButtonBitmap(sb->w, sb->h, sb->state, L"wasabi.scrollbar.horizontal.grip");
+ sb->bitmap = bmp;
+ break;
+ }
+ case SKINBITMAP_SCROLLBARUPBUTTON: {
+ HBITMAP bmp = generateButtonBitmap(sb->w, sb->h, sb->state, L"wasabi.button.label.arrow.up");
+ sb->bitmap = bmp;
+ break;
+ }
+ case SKINBITMAP_SCROLLBARDOWNBUTTON: {
+ HBITMAP bmp = generateButtonBitmap(sb->w, sb->h, sb->state, L"wasabi.button.label.arrow.down");
+ sb->bitmap = bmp;
+ break;
+ }
+ case SKINBITMAP_SCROLLBARLEFTBUTTON: {
+ HBITMAP bmp = generateButtonBitmap(sb->w, sb->h, sb->state, L"wasabi.button.label.arrow.left");
+ sb->bitmap = bmp;
+ break;
+ }
+ case SKINBITMAP_SCROLLBAR_FF_UPBUTTON: {
+ HBITMAP bmp = generateButtonBitmap(sb->w, sb->h, SCROLLBARSTATE_NORMAL,
+ ((sb->state==SCROLLBARSTATE_PRESSED)?L"wasabi.scrollbar.vertical.left.pressed":
+ ((sb->state==SCROLLBARSTATE_HOVER)?L"wasabi.scrollbar.vertical.left.hover":
+ L"wasabi.scrollbar.vertical.left")));
+ sb->bitmap = bmp;
+ break;
+ }
+ case SKINBITMAP_SCROLLBAR_FF_DOWNBUTTON: {
+ HBITMAP bmp = generateButtonBitmap(sb->w, sb->h, SCROLLBARSTATE_NORMAL,
+ ((sb->state==SCROLLBARSTATE_PRESSED)?L"wasabi.scrollbar.vertical.right.pressed":
+ ((sb->state==SCROLLBARSTATE_HOVER)?L"wasabi.scrollbar.vertical.right.hover":
+ L"wasabi.scrollbar.vertical.right")));
+ sb->bitmap = bmp;
+ break;
+ }
+ case SKINBITMAP_SCROLLBAR_FF_LEFTBUTTON: {
+ HBITMAP bmp = generateButtonBitmap(sb->w, sb->h, SCROLLBARSTATE_NORMAL,
+ ((sb->state==SCROLLBARSTATE_PRESSED)?L"wasabi.scrollbar.horizontal.left.pressed":
+ ((sb->state==SCROLLBARSTATE_HOVER)?L"wasabi.scrollbar.horizontal.left.hover":
+ L"wasabi.scrollbar.horizontal.left")));
+ sb->bitmap = bmp;
+ break;
+ }
+ case SKINBITMAP_SCROLLBAR_FF_RIGHTBUTTON: {
+ HBITMAP bmp = generateButtonBitmap(sb->w, sb->h, SCROLLBARSTATE_NORMAL,
+ ((sb->state==SCROLLBARSTATE_PRESSED)?L"wasabi.scrollbar.horizontal.right.pressed":
+ ((sb->state==SCROLLBARSTATE_HOVER)?L"wasabi.scrollbar.horizontal.right.hover":
+ L"wasabi.scrollbar.horizontal.right")));
+ sb->bitmap = bmp;
+ break;
+ }
+ case SKINBITMAP_SCROLLBAR_FF_BARHBUTTON: {
+ HBITMAP bmp = generateButtonBitmap(sb->w, sb->h, SCROLLBARSTATE_NORMAL,
+ ((sb->state==SCROLLBARSTATE_PRESSED)?L"wasabi.scrollbar.horizontal.button.pressed":
+ ((sb->state==SCROLLBARSTATE_HOVER)?L"wasabi.scrollbar.horizontal.button.hover":
+ L"wasabi.scrollbar.horizontal.button")));
+ sb->bitmap = bmp;
+ break;
+ }
+ case SKINBITMAP_SCROLLBAR_FF_BARVBUTTON: {
+ HBITMAP bmp = generateButtonBitmap(sb->w, sb->h, SCROLLBARSTATE_NORMAL,
+ ((sb->state==SCROLLBARSTATE_PRESSED)?L"wasabi.scrollbar.vertical.button.pressed":
+ ((sb->state==SCROLLBARSTATE_HOVER)?L"wasabi.scrollbar.vertical.button.hover":
+ L"wasabi.scrollbar.vertical.button.pressed")));
+ sb->bitmap = bmp;
+ break;
+ }
+ }
+
+ #if 0 // debug
+
+ HDC ddc = GetDC(NULL);
+ HDC sdc = CreateCompatibleDC(ddc);
+ SelectObject(sdc, sb->bitmap);
+
+ BitBlt(ddc, 100, 100, sb->w, sb->h, sdc, 0, 0, SRCCOPY);
+
+ DeleteObject(sdc);
+ ReleaseDC(NULL, ddc);
+
+ #endif
+}
+
+ColorThemeMonitor::ColorThemeMonitor() {
+ WASABI_API_SYSCB->syscb_registerCallback(this);
+}
+
+ColorThemeMonitor::~ColorThemeMonitor() {
+ WASABI_API_SYSCB->syscb_deregisterCallback(this);
+}
+
+int ColorThemeMonitor::skincb_onColorThemeChanged( const wchar_t *colortheme )
+{
+ SendMessageW( wa2.getMainWindow(), WM_WA_IPC, (WPARAM) colortheme, IPC_FF_ONCOLORTHEMECHANGED );
+ return 1;
+}
diff --git a/Src/Plugins/General/gen_ff/ff_ipc.h b/Src/Plugins/General/gen_ff/ff_ipc.h
new file mode 100644
index 00000000..6a422e2a
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/ff_ipc.h
@@ -0,0 +1,86 @@
+#ifndef _FF_IPC_H
+#define _FF_IPC_H
+
+// -----------------------------------------------------------------------------------------------------
+// ----- IPC_FF_GETSKINCOLOR : Ask for a skin color -- the color is filtered for the current theme -----
+// -----------------------------------------------------------------------------------------------------
+
+#define IPC_FF_GETSKINCOLOR IPC_FF_FIRST + 1 // data = ff_skincolor struct with .colorname, fills in .color
+
+typedef struct {
+ char colorname[256];
+ COLORREF color;
+} ff_skincolor;
+
+// List of default colors as of june 30, 2003. see freeform/xml/wasabi/xml/system-colors.xml for latest/complete list
+
+// Trees
+ #define SKINCOLOR_TREE_ITEMTEXT "wasabi.tree.text"
+ #define SKINCOLOR_TREE_SELITEMBKG L"wasabi.tree.selected"
+ #define SKINCOLOR_TREE_HILITEDROP "wasabi.tree.hiliteddrop"
+
+// Lists
+ #define SKINCOLOR_LIST_ITEMTEXT L"wasabi.list.text"
+ #define SKINCOLOR_LIST_SELITEMBKG "wasabi.list.item.selected"
+ #define SKINCOLOR_LIST_FOCUSITEMBKG "wasabi.list.item.focused"
+ #define SKINCOLOR_LIST_COLUMNBKG L"wasabi.list.column.background"
+ #define SKINCOLOR_LIST_COLUMNTEXT L"wasabi.list.column.text"
+ #define SKINCOLOR_LIST_SELITEMTEXT "wasabi.list.item.selected.fg"
+ #define SKINCOLOR_LIST_COLUMNSEPARATOR "wasabi.list.column.separator"
+
+// Buttons
+ #define SKINCOLOR_BUTTON_TEXT L"wasabi.button.text"
+ #define SKINCOLOR_BUTTON_HILITETEXT "wasabi.button.hiliteText"
+ #define SKINCOLOR_BUTTON_DIMMEDTEXT "wasabi.button.dimmedText"
+
+
+// ----------------------------------------------------------------------------------------
+// ----- IPC_FF_GENSKINBITMAP: Ask gen_ff to create a bitmap of various skin elements -----
+// ----------------------------------------------------------------------------------------
+
+// NOTE: You should free the hbitmap eventually using DeleteObject
+
+#define IPC_FF_GENSKINBITMAP IPC_FF_FIRST + 2 // data = ff_skinbitmap with bitmap .id .w .h and .state, fills in .bitmap
+
+typedef struct {
+ int id; // see below
+ int w, h;
+ int state; // id specific, see below
+ HBITMAP bitmap;
+} ff_skinbitmap;
+
+// Bitmap IDs :
+
+#define SKINBITMAP_BUTTON 0 // Generate a button bitmap. states are as follows :
+
+ #define BUTTONSTATE_NORMAL 0
+ #define BUTTONSTATE_PUSHED 1
+
+#define SKINBITMAP_SCROLLBARUPBUTTON 1 // Generate a scrollbar up button bitmap. states are button states
+#define SKINBITMAP_SCROLLBARDOWNBUTTON 2 // Generate a scrollbar down button bitmap. states are button states
+#define SKINBITMAP_SCROLLBARLEFTBUTTON 3 // Generate a scrollbar left button bitmap. states are button states
+#define SKINBITMAP_SCROLLBARRIGHTBUTTON 4 // Generate a scrollbar right button bitmap. states are button states
+#define SKINBITMAP_SCROLLBARVBUTTON 5 // Generate a scrollbar vertical button bitmap. states are button states
+#define SKINBITMAP_SCROLLBARHBUTTON 6 // Generate a scrollbar horizontal button bitmap. states are button states
+
+#define SKINBITMAP_SCROLLBAR_FF_UPBUTTON 7 // Generate a freeform scrollbar up button bitmap. states are scrollbar states
+#define SKINBITMAP_SCROLLBAR_FF_DOWNBUTTON 8 // Generate a freeform scrollbar down button bitmap. states are scrollbar states
+#define SKINBITMAP_SCROLLBAR_FF_LEFTBUTTON 9 // Generate a freeform scrollbar left button bitmap. states are scrollbar states
+#define SKINBITMAP_SCROLLBAR_FF_RIGHTBUTTON 10 // Generate a freeform scrollbar right button bitmap. states are scrollbar states
+#define SKINBITMAP_SCROLLBAR_FF_BARHBUTTON 11 // Generate a freeform scrollbar vertical button bitmap. states are scrollbar states
+#define SKINBITMAP_SCROLLBAR_FF_BARVBUTTON 12 // Generate a freeform scrollbar horizontal button bitmap. states are scrollbar states
+
+ #define SCROLLBARSTATE_NORMAL 0
+ #define SCROLLBARSTATE_PRESSED 1
+ #define SCROLLBARSTATE_HOVER 2
+
+// -----------------------------------------------------------------------------------------------
+// ----- IPC_FF_ONCOLORTHEMECHANGED: CALLBACK - sent when the skin's color theme has changed -----
+// -----------------------------------------------------------------------------------------------
+
+#define IPC_FF_ONCOLORTHEMECHANGED IPC_FF_FIRST + 3 // data = name of the new color theme (const char *)
+#define IPC_FF_ISMAINWND IPC_FF_FIRST + 4 // data = hwnd, returns 1 if hwnd is main window or any of its windowshade
+#define IPC_FF_GETCONTENTWND IPC_FF_FIRST + 5 // data = HWND, returns the wa2 window that is embedded in the window's container (ie if hwnd is the pledit windowshade hwnd, it returns the wa2 pledit hwnd). if no content is found (ie, the window has nothing embedded) it returns the parameter you gave it
+#define IPC_FF_NOTIFYHOTKEY IPC_FF_FIRST + 6 // data = const char * to hotkey description
+
+#endif
diff --git a/Src/Plugins/General/gen_ff/fsmonitor.cpp b/Src/Plugins/General/gen_ff/fsmonitor.cpp
new file mode 100644
index 00000000..31a3decd
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/fsmonitor.cpp
@@ -0,0 +1,174 @@
+#include "precomp__gen_ff.h"
+#include "fsmonitor.h"
+
+#define tag L"wa5_fsmonitorclass"
+
+LRESULT CALLBACK fsMonitorWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
+extern HINSTANCE hInstance;
+//------------------------------------------------------------------------
+FullScreenMonitor::FullScreenMonitor()
+{
+ m_go_fs_timer_set = 0;
+ m_cancel_fs_timer_set = 0;
+ m_fs = 0;
+ WNDCLASSW wc;
+ if (!GetClassInfoW( hInstance, tag, &wc ))
+ {
+ MEMSET( &wc, 0, sizeof( wc ) );
+ wc.lpfnWndProc = fsMonitorWndProc;
+ wc.hInstance = hInstance; // hInstance of DLL
+ wc.lpszClassName = tag; // our window class name
+ wc.style = 0;
+
+ int _r = RegisterClassW( &wc );
+ ASSERTPR( _r, "cannot create fsmonitor wndclass" );
+ }
+
+ hWnd = CreateWindowExW( 0, tag, L"", 0, 0, 0, 1, 1, NULL, NULL, hInstance, NULL );
+
+ ASSERT( hWnd );
+
+ SetWindowLongPtrW( hWnd, GWLP_USERDATA, (LONG_PTR) this );
+
+ APPBARDATA abd;
+
+ abd.cbSize = sizeof( APPBARDATA );
+ abd.hWnd = hWnd;
+ abd.uCallbackMessage = APPBAR_CALLBACK;
+
+ SHAppBarMessage( ABM_NEW, &abd );
+}
+
+//------------------------------------------------------------------------
+FullScreenMonitor::~FullScreenMonitor()
+{
+ APPBARDATA abd;
+
+ abd.cbSize = sizeof( APPBARDATA );
+ abd.hWnd = hWnd;
+
+ SHAppBarMessage( ABM_REMOVE, &abd );
+
+ if (IsWindow( hWnd ))
+ DestroyWindow( hWnd );
+}
+
+//------------------------------------------------------------------------
+void FullScreenMonitor::registerCallback( FSCallback *cb )
+{
+ if (m_callbacks.haveItem( cb )) return;
+ m_callbacks.addItem( cb );
+}
+
+
+//------------------------------------------------------------------------
+void FullScreenMonitor::unregisterCallback( FSCallback *cb )
+{
+ m_callbacks.removeItem( cb );
+}
+
+//------------------------------------------------------------------------
+void FullScreenMonitor::onGoFullscreen()
+{
+ if (m_cancel_fs_timer_set)
+ {
+ timerclient_killTimer( 2 );
+ m_cancel_fs_timer_set = 0;
+ }
+ else
+ {
+ timerclient_setTimer( 1, 250 );
+ m_go_fs_timer_set = 1;
+ }
+}
+
+//------------------------------------------------------------------------
+void FullScreenMonitor::onCancelFullscreen()
+{
+ if (m_go_fs_timer_set)
+ {
+ timerclient_killTimer( 1 );
+ m_go_fs_timer_set = 0;
+ }
+ else
+ {
+ timerclient_setTimer( 2, 250 );
+ m_cancel_fs_timer_set = 1;
+ }
+}
+
+//------------------------------------------------------------------------
+void FullScreenMonitor::sendGoFSCallbacks()
+{
+ foreach( m_callbacks );
+ m_callbacks.getfor()->onGoFullscreen();
+ endfor;
+}
+
+//------------------------------------------------------------------------
+void FullScreenMonitor::sendCancelFSCallbacks()
+{
+ foreach( m_callbacks );
+ m_callbacks.getfor()->onCancelFullscreen();
+ endfor;
+}
+
+//------------------------------------------------------------------------
+void FullScreenMonitor::timerclient_timerCallback( int id )
+{
+ if (id == 1)
+ {
+ timerclient_killTimer( 1 );
+ m_go_fs_timer_set = 0;
+ sendGoFSCallbacks();
+ }
+ else if (id == 2)
+ {
+ timerclient_killTimer( 2 );
+ m_cancel_fs_timer_set = 0;
+ sendCancelFSCallbacks();
+ }
+}
+
+//------------------------------------------------------------------------
+int FullScreenMonitor::wndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+ switch (uMsg)
+ {
+ case APPBAR_CALLBACK:
+ {
+ switch (wParam)
+ {
+ case ABN_FULLSCREENAPP:
+ //DebugString("ABN_FULLSCREENAPP\n");
+ if (lParam && !m_fs)
+ {
+ m_fs = 1;
+ onGoFullscreen();
+ }
+ else if (!lParam && m_fs)
+ {
+ m_fs = 0;
+ onCancelFullscreen();
+ }
+ break;
+ }
+ }
+ }
+ return DefWindowProc( hwnd, uMsg, wParam, lParam );
+}
+
+//------------------------------------------------------------------------
+LRESULT CALLBACK fsMonitorWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+#ifdef WIN32
+ FullScreenMonitor *gThis = (FullScreenMonitor *) GetWindowLongPtrW( hwnd, GWLP_USERDATA );
+ if (!gThis)
+ return DefWindowProc( hwnd, uMsg, wParam, lParam );
+ else
+ return gThis->wndProc( hwnd, uMsg, wParam, lParam );
+#else
+ return 0;
+#endif
+}
+
diff --git a/Src/Plugins/General/gen_ff/fsmonitor.h b/Src/Plugins/General/gen_ff/fsmonitor.h
new file mode 100644
index 00000000..4cae9ce0
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/fsmonitor.h
@@ -0,0 +1,39 @@
+#ifndef _FS_MONITOR_H
+#define _FS_MONITOR_H
+
+#include <bfc/ptrlist.h>
+#include <api/timer/timerclient.h>
+
+class FSCallback {
+public:
+ virtual void onGoFullscreen()=0;
+ virtual void onCancelFullscreen()=0;
+};
+
+class FullScreenMonitor : public TimerClientDI {
+public:
+ FullScreenMonitor();
+ virtual ~FullScreenMonitor();
+
+ void registerCallback(FSCallback *cb);
+ void unregisterCallback(FSCallback *cb);
+
+ int isFullScreen() { return m_fs; }
+
+ int wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ void timerclient_timerCallback(int id);
+
+private:
+ void onGoFullscreen();
+ void onCancelFullscreen();
+ void sendGoFSCallbacks();
+ void sendCancelFSCallbacks();
+ PtrList<FSCallback> m_callbacks;
+ HWND hWnd;
+ int m_fs;
+ int m_go_fs_timer_set;
+ int m_cancel_fs_timer_set;
+};
+
+#endif
diff --git a/Src/Plugins/General/gen_ff/gen.h b/Src/Plugins/General/gen_ff/gen.h
new file mode 100644
index 00000000..53b7431a
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/gen.h
@@ -0,0 +1 @@
+#include "../Winamp/gen.h"
diff --git a/Src/Plugins/General/gen_ff/gen_ff.rc b/Src/Plugins/General/gen_ff/gen_ff.rc
new file mode 100644
index 00000000..033885fb
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/gen_ff.rc
@@ -0,0 +1,543 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""gen_ff.rc2""\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_PREFS_GENERAL DIALOGEX 0, 0, 261, 228
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ GROUPBOX "Desktop Alpha Blending",IDC_STATIC_DA1,4,3,256,48
+ LTEXT "Desktop Alpha Blending allows some skins to display subtle shadows, smoothed edges, and other visual enhancements.",IDC_STATIC,9,15,244,16
+ CONTROL "Enable Desktop Alpha Blending (when requested by the skin)",IDC_CHECK_DESKTOPALPHA,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,35,210,10
+ GROUPBOX "Timers Resolution : 33ms",IDC_STATIC_TIMERRES,4,54,256,37
+ CONTROL "Slider1",IDC_SLIDER_TIMERRESOLUTION,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,9,66,190,10
+ PUSHBUTTON "Optimize...",IDC_BUTTON_AUTOTIMERRES,201,63,52,13
+ LTEXT "Smoother",IDC_STATIC,12,76,32,8
+ RTEXT "Choppier",IDC_STATIC,165,76,30,8
+ GROUPBOX "Text Scroll Speed : Average",IDC_STATIC_TICKER,4,94,256,34
+ CONTROL "Slider1",IDC_SLIDER_TICKERSPEED,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,9,105,111,10
+ LTEXT "Faster",IDC_STATIC,11,114,22,8
+ LTEXT "Slower",IDC_STATIC,100,114,23,8,0,WS_EX_RIGHT
+ LTEXT "Move text by",IDC_STATIC,145,106,44,8
+ EDITTEXT IDC_EDIT_INCREMENT,190,104,30,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_SPIN_INCREMENT,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,209,103,10,14
+ LTEXT "pixels",IDC_STATIC,225,106,19,8
+ GROUPBOX "Miscellaneous",IDC_STATIC,4,131,256,86
+ CONTROL "Enable tooltips",IDC_CHECK_TOOLTIPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,144,65,10
+ CONTROL "Dock windows at ",IDC_CHECK_DOCKING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,156,67,11
+ EDITTEXT IDC_EDIT_DOCKDISTANCE,79,155,30,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_SPIN_DOCKDISTANCE,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,97,154,10,14
+ LTEXT "pixels",IDC_STATIC,111,157,18,8
+ CONTROL "Dock toolbars at ",IDC_CHECK_DOCKING2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,170,67,11
+ EDITTEXT IDC_EDIT_DOCKDISTANCE2,79,169,30,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_SPIN_DOCKDISTANCE2,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,97,168,11,14
+ LTEXT "pixels",IDC_STATIC,111,171,18,8
+ LTEXT "Wait",IDC_STATIC,11,186,16,8
+ EDITTEXT IDC_EDIT_SHOWTIME,30,184,35,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_SPIN_SHOWTIME,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,50,183,10,14
+ LTEXT "ms before showing docked toolbars",IDC_STATIC,70,186,114,8
+ LTEXT "Wait",IDC_STATIC,11,201,16,8
+ EDITTEXT IDC_EDIT_HIDETIME,30,199,35,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_SPIN_HIDETIME,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,49,198,10,14
+ LTEXT "ms before hiding docked toolbars",IDC_STATIC,70,201,106,8
+END
+
+IDD_PREFS DIALOGEX 0, 0, 271, 246
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ CONTROL "Tab1",IDC_TAB1,"SysTabControl32",WS_TABSTOP,0,0,271,246
+END
+
+IDD_PREFS_THEMES DIALOGEX 0, 0, 261, 228
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ LISTBOX IDC_LIST1,4,6,256,203,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "&Set Theme",IDC_BUTTON_SETTHEME,210,212,50,13
+END
+
+IDD_ABOUT DIALOGEX 0, 0, 278, 175
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION
+CAPTION "About"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,220,157,50,13
+ CONTROL "",IDC_STATIC_GROUP,"Static",SS_BLACKFRAME | SS_SUNKEN,7,7,263,146
+END
+
+IDD_AUTOTIMERRES DIALOGEX 0, 0, 195, 90
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Auto Detection of Optimum Timers Resolution"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ DEFPUSHBUTTON "Go",IDOK,85,70,50,13
+ PUSHBUTTON "Cancel",IDCANCEL,138,70,50,13
+ CTEXT "Auto detection works best if other applications are not saturating the CPU.\n\nBefore you continue, please start playing a song.\n\nPress Go when ready.\n(animations will temporarily slow down)",IDC_TXT,7,7,181,57
+END
+
+IDD_CUSTOMSCALE DIALOGEX 0, 0, 165, 70
+STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_TOOLWINDOW
+CAPTION "Custom Scale"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Scale : 100%",IDC_STATIC_SCALE,7,7,151,37
+ CONTROL "Slider1",IDC_SLIDER_CUSTOMSCALE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,13,17,139,11
+ LTEXT "10%",IDC_STATIC,17,30,18,8
+ LTEXT "300%",IDC_STATIC,130,30,21,8
+ DEFPUSHBUTTON "OK",IDOK,54,50,50,13
+ PUSHBUTTON "Cancel",IDCANCEL,108,50,50,13
+END
+
+IDD_PREFS_FONTS DIALOGEX 0, 0, 261, 228
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ CONTROL "Use FreeType TrueType font rendering for older skins",IDC_CHECK_FREETYPETTF,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,4,191,10
+ LTEXT "Charmap Encoding :",IDC_STATIC_CHARMAP,15,18,65,8
+ COMBOBOX IDC_COMBO_CHARMAP,85,16,170,235,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Alternate Fonts",IDC_STATIC_ALTFONTS,4,33,256,40
+ CONTROL "Use the alternate fonts if the skin defines them",IDC_CHECK_ALTFONTS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,45,169,10
+ CONTROL "Keep primary font in strings that contain only 7-bit characters",IDC_CHECK_NO_ALT_7BIT_OVERRIDE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,58,215,10
+ GROUPBOX "Font Mapper",IDC_STATIC,4,76,256,105
+ CONTROL "Use skin font mapper",IDC_CHECK_USEFONTMAPPER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,88,85,10
+ PUSHBUTTON "Configure skin font mapping...",IDC_BUTTON_FONTMAPPER,133,86,120,13
+ CONTROL "Allow use of bitmap fonts that have not been mapped",IDC_CHECK_ALLOWBITMAPFONTS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,101,188,10
+ LTEXT "Replace with :",IDC_STATIC,17,128,46,8
+ GROUPBOX "TrueType Replacement for Winamp Charset bitmap fonts",IDC_STATIC_TTFOVERRIDE,10,114,244,62
+ COMBOBOX IDC_COMBO_TTFOVERRIDE,67,126,179,151,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Slider1",IDC_SLIDER_SCALETTFOVERRIDE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,16,142,231,10
+ LTEXT "Decrease size",IDC_STATIC_DECREASESIZE,20,151,46,8
+ CTEXT "100%",IDC_STATIC_TTFSCALE,118,151,31,8
+ LTEXT "Increase size",IDC_STATIC_INCREASESIZE,201,151,42,8
+ CONTROL "Keep bitmap font in strings that contain only 7-bit characters",IDC_NO_7BIT_OVERRIDE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,162,210,10
+ GROUPBOX "Default / Fallback Font",IDC_STATIC,4,185,256,43
+ LTEXT "If a font was not specified or cannot be found, use this font at this scale :",IDC_STATIC,10,196,243,8
+ COMBOBOX IDC_COMBO_DEFAULTFONT,9,209,100,151,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Slider1",IDC_SLIDER_SCALEDEFAULTFONT,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,116,206,139,10
+ LTEXT "Decrease size",IDC_STATIC_DECREASESIZE2,119,214,46,8
+ CTEXT "100%",IDC_STATIC_SCALEDEFAULTFONT,172,214,31,8
+ LTEXT "Increase size",IDC_STATIC_INCREASESIZE2,210,214,42,8
+ CTEXT "100%",IDC_STATIC_SCALEDEFAULTFONT2,174,214,31,8
+END
+
+IDD_PREFS_WINDOWS DIALOGEX 0, 0, 260, 228
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ GROUPBOX "Scaling",IDC_STATIC,4,3,256,76
+ CONTROL "Link all windows in all skins:",IDC_CHECK_LINKALLRATIO,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,15,103,10
+ CTEXT "100%",IDC_STATIC_SCALE,159,10,51,8
+ LTEXT "10%",IDC_STATIC_SCALE11,124,17,16,8
+ CONTROL "",IDC_SLIDER_CUSTOMSCALE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,142,18,84,10
+ LTEXT "300%",IDC_STATIC_SCALE301,227,17,20,8
+ CONTROL "WindowShade scale follows Normal Window Scale",IDC_CHECK_LINKRATIO,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,28,173,10
+ GROUPBOX "On Window Close/Reopen",IDC_STATIC,10,41,244,32
+ COMBOBOX IDC_COMBO_SCALE,16,54,232,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Opacity",IDC_STATIC_OPACITY,4,81,256,138
+ CONTROL "Link all windows in all skins:",IDC_CHECK_LINKALLALPHA,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,92,102,10
+ COMBOBOX IDC_COMBO_OPACITY,11,106,98,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Slider1",IDC_SLIDER_CUSTOMALPHA,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,114,106,140,10
+ LTEXT "Transparent",IDC_STATIC_TRANSP,117,116,40,8
+ CTEXT "100%",IDC_STATIC_ALPHA,176,116,28,8
+ LTEXT "Opaque",IDC_STATIC_OPAQUE,223,116,26,8
+ CONTROL "WindowShade opacity follows Normal Window opacity",IDC_CHECK_LINKALPHA,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,128,186,10
+ GROUPBOX "Auto Opaque",IDC_STATIC_AUTOON,10,142,244,71
+ LTEXT "To use Auto Opaque on a window without linking all of them, use the context menu on that window and select Window Settings, Opacity.",IDC_STATIC_AUTOONTXT,15,153,224,18
+ LTEXT "Fade in :",IDC_STATIC_FADEIN2,15,174,28,8
+ CONTROL "Slider1",IDC_SLIDER_FADEIN,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,51,175,102,10
+ LTEXT "250ms",IDC_STATIC_FADEIN,154,174,31,8
+ LTEXT "Hold :",IDC_STATIC_HOLD2,15,186,22,8
+ CONTROL "Slider1",IDC_SLIDER_HOLD,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,51,186,102,10
+ LTEXT "2000ms",IDC_STATIC_HOLD,154,186,32,8
+ LTEXT "Fade out :",IDC_STATIC_FADEOUT2,15,198,34,8
+ CONTROL "Slider1",IDC_SLIDER_FADEOUT,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,51,198,102,10
+ LTEXT "2000ms",IDC_STATIC_FADEOUT,154,198,32,8
+ GROUPBOX "Extend Hover",IDC_STATIC_EXTENDBOX,183,177,64,30
+ EDITTEXT IDC_EDIT_EXTEND,189,189,30,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_SPIN_EXTEND,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,211,188,10,14
+ LTEXT "pixels",IDC_STATIC_EXTEND,224,191,19,8
+END
+
+IDD_CUSTOMALPHA DIALOGEX 0, 0, 165, 70
+STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_TOOLWINDOW
+CAPTION "Custom Opacity"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Opacity : 100%",IDC_STATIC_ALPHA,7,7,151,37
+ CONTROL "Slider1",IDC_SLIDER_CUSTOMALPHA,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,13,17,139,11
+ LTEXT "10%",IDC_STATIC,17,30,18,8
+ LTEXT "100%",IDC_STATIC,130,30,21,8
+ DEFPUSHBUTTON "OK",IDOK,54,50,50,13
+ PUSHBUTTON "Cancel",IDCANCEL,108,50,50,13
+END
+
+IDD_FONTMAPPER DIALOGEX 0, 0, 277, 169
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Font Mapper"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ CONTROL "List2",IDC_LIST_MAPPINGS,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP,7,7,263,80
+ LTEXT "Map when using:",IDC_STATIC,9,91,35,18
+ CONTROL "This skin",IDC_RADIO_THISSKIN,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,47,92,44,8
+ CONTROL "All skins",IDC_RADIO_ALLSKINS,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,47,101,41,8
+ LTEXT "Map font :",IDC_STATIC,9,114,33,8
+ COMBOBOX IDC_COMBO_SKINFONTS,46,112,132,122,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Into :",IDC_STATIC,9,128,33,8
+ COMBOBOX IDC_COMBO_FONTS,46,126,132,122,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Scale :",IDC_STATIC,9,144,23,8
+ CONTROL "Slider1",IDC_SLIDER_SCALE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,42,144,140,10
+ LTEXT "Decrease size",IDC_STATIC,43,154,46,8
+ LTEXT "100%",IDC_STATIC_SCALE,104,155,20,8
+ LTEXT "Increase size",IDC_STATIC,138,154,42,8
+ PUSHBUTTON "Delete",IDC_BUTTON_DEL,212,90,58,13
+ PUSHBUTTON "Set",IDC_BUTTON_SET,212,111,58,13
+ PUSHBUTTON "New",IDC_BUTTON_NEW,212,127,58,13
+ DEFPUSHBUTTON "Close",IDOK,220,149,50,13
+END
+
+IDD_PREFS_SKIN DIALOGEX 0, 0, 261, 228
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "",IDC_STATIC_GROUP,4,6,256,200,0,WS_EX_CLIENTEDGE
+ CTEXT "-",IDC_STATIC_EMPTY,34,23,192,162
+ PUSHBUTTON "Skin Options Menu",IDC_BUTTON_SKINSPECIFIC,74,212,114,13
+END
+
+IDD_MEDIA_DOWNLOADER DIALOGEX 0, 0, 307, 59
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Download"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "",IDC_URL,7,7,293,10
+ LTEXT "",IDC_PROGRESS,7,28,293,8
+ LTEXT "",IDC_DOWNLOADTO,7,44,293,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_PREFS_GENERAL, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 260
+ END
+
+ IDD_PREFS_THEMES, DIALOG
+ BEGIN
+ RIGHTMARGIN, 260
+ END
+
+ IDD_ABOUT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 270
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 170
+ END
+
+ IDD_AUTOTIMERRES, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 188
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 83
+ END
+
+ IDD_CUSTOMSCALE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 158
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 63
+ END
+
+ IDD_PREFS_FONTS, DIALOG
+ BEGIN
+ RIGHTMARGIN, 260
+ END
+
+ IDD_CUSTOMALPHA, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 158
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 63
+ END
+
+ IDD_FONTMAPPER, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 270
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 162
+ END
+
+ IDD_MEDIA_DOWNLOADER, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 300
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 52
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_CONTROLMENU MENU
+BEGIN
+ POPUP "ControlMenu"
+ BEGIN
+ POPUP "&Opacity"
+ BEGIN
+ MENUITEM "1&00%", ID_CONTROLMENU_OPACITY_100
+ MENUITEM "&90%", ID_CONTROLMENU_OPACITY_90
+ MENUITEM "&80%", ID_CONTROLMENU_OPACITY_80
+ MENUITEM "&70%", ID_CONTROLMENU_OPACITY_70
+ MENUITEM "&60%", ID_CONTROLMENU_OPACITY_60
+ MENUITEM "&50%", ID_CONTROLMENU_OPACITY_50
+ MENUITEM "&40%", ID_CONTROLMENU_OPACITY_40
+ MENUITEM "&30%", ID_CONTROLMENU_OPACITY_30
+ MENUITEM "&20%", ID_CONTROLMENU_OPACITY_20
+ MENUITEM "&10%", ID_CONTROLMENU_OPACITY_10
+ MENUITEM "&Custom", ID_CONTROLMENU_OPACITY_CUSTOM
+ MENUITEM SEPARATOR
+ MENUITEM "Opaque on &Focus", ID_CONTROLMENU_OPACITY_AUTO100_FOCUS
+ MENUITEM "Opaque on &Hover", ID_CONTROLMENU_OPACITY_AUTO100_HOVER
+ END
+ POPUP "&Scaling"
+ BEGIN
+ MENUITEM "&50%", ID_CONTROLMENU_SCALING_50
+ MENUITEM "&75%", ID_CONTROLMENU_SCALING_75
+ MENUITEM "&100%", ID_CONTROLMENU_SCALING_100
+ MENUITEM "125%", ID_CONTROLMENU_SCALING_125
+ MENUITEM "150%", ID_CONTROLMENU_SCALING_150
+ MENUITEM "&200%", ID_CONTROLMENU_SCALING_200
+ MENUITEM "250%", ID_CONTROLMENU_SCALING_250
+ MENUITEM "&300%", ID_CONTROLMENU_SCALING_300
+ MENUITEM "&Custom", ID_CONTROLMENU_SCALING_CUSTOM
+ MENUITEM SEPARATOR
+ MENUITEM "&Locked", ID_CONTROLMENU_SCALING_LOCKED
+ MENUITEM "&Temporary", ID_CONTROLMENU_SCALING_FOLLOWDOUBLESIZE
+ END
+ POPUP "Docked Toolbar"
+ BEGIN
+ MENUITEM "Auto-&Hide", ID_CONTROLMENU_TOOLBAR_AUTOHIDE
+ MENUITEM "&Always On Top", ID_CONTROLMENU_TOOLBAR_ALWAYSONTOP
+ MENUITEM SEPARATOR
+ MENUITEM "Top", ID_CONTROLMENU_TOOLBAR_TOP
+ MENUITEM "Left", ID_CONTROLMENU_TOOLBAR_LEFT
+ MENUITEM "Right", ID_CONTROLMENU_TOOLBAR_RIGHT
+ MENUITEM "Bottom", ID_CONTROLMENU_TOOLBAR_BOTTOM
+ MENUITEM "Not docked", ID_CONTROLMENU_TOOLBAR_DISABLED
+ MENUITEM SEPARATOR
+ MENUITEM "Dock/Undock Windows by Dragging", ID_CONTROLMENU_TOOLBAR_AUTODOCKONDRAG
+ END
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_NULLSOFT_MODERN_SKINS "Nullsoft Modern Skins Support v%s"
+ 65535 "{ACD05A75-030B-4943-A100-540DAD98FB00}"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_SEND_TO "Send to:"
+ IDS_NO_THEME_AVAILABLE "No theme available"
+ IDS_COLOR_THEMES "Color Themes"
+ IDS_CURRENT_SKIN "Current Skin"
+ IDS_NO_SKIN_LOADED "No modern skin loaded"
+ IDS_MODERN_SKIN_SUPPORT_CLASSIC
+ "Modern Skin support (switch to a modern skin for a much more interesting about box =)"
+ IDS_MODERN_SKIN_SUPPORT "Modern Skin support"
+ IDS_CUSTOM_X_PERCENT "&Custom (%d%%)..."
+ IDS_CUSTOM "&Custom..."
+ IDS_WINDOW_SETTINGS "Window Settings"
+ IDS_SCALE_X_PERCENT "Scale : %d%%"
+ IDS_OPACITY_X_PERCENT "Opacity : %d%%"
+ IDS_GHK_SHOW_NOTIFICATION "Playback: Show notification"
+ IDS_MODERN_SKINS "Modern Skins"
+ IDS_GENERAL "General"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_ALPHA_BLENDING "Alpha Blending"
+ IDS_FONT_RENDERING "Font Rendering"
+ IDS_ERROR_WHILE_LOADING_SKIN_WINDOW "Error while loading skin window"
+ IDS_NO_OPTIONS_AVAILABLE_FOR_THIS_SKIN
+ "No Options Available For This Skin"
+ IDS_AUTO_UNICODE_LATIN1_ASCII "Auto (Unicode -> Latin-1 -> ASCII)"
+ IDS_FONT "Font"
+ IDS_MAPPING "Mapping"
+ IDS_SCALE "Scale"
+ IDS_TYPE "Type"
+ IDS_THIS_SKIN "This skin"
+ IDS_ALL_SKINS "All skins"
+ IDS_FASTER "Faster"
+ IDS_FAST "Fast"
+ IDS_AVERAGE "Average"
+ IDS_SLOW "Slow"
+ IDS_SLOWER "Slower"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_FAILED_TO_DETECT_OPTIMAL_RESOLUTION
+ "\n\nFailed to detect optimal resolution.\n\nThis machine may be very slow, or the CPU may be otherwise too busy for auto-detection to work."
+ IDS_AUTO_DETECTING "\n\nAuto detecting...\n\nNow trying %dms."
+ IDS_PREPARING_AUTO_DETECTION "\n\n\nPreparing auto detection..."
+ IDS_AUTO_DETECTION_SUCCESSFUL
+ "\n\nAuto detection successful.\n\nOptimum Resolution : %dms"
+ IDS_ACCEPT "Accept"
+ IDS_N_A "n/a"
+ IDS_TIMERS_RESOLUTION "Timers Resolution : %dms"
+ IDS_TEXT_SCROLL_SPEED "Text Scroll Speed : %s"
+ IDS_CROSSFADER_ONLY_UNDER_OUT_DS
+ "Crossfader is only supported by DirectSound Output.\nWould you like to change your Output plug-in now?"
+ IDS_NOT_SUPPORTED "Not Supported"
+ IDS_PLAYLIST_EDITOR "Playlist Editor"
+ IDS_VIDEO "Video"
+ IDS_MONO " mono"
+ IDS_STEREO " stereo"
+ IDS_X_CHANNELS " %d Channels"
+ IDS_BY_SPACE "by "
+END
+
+STRINGTABLE
+BEGIN
+ IDS_COULD_NOT_FIND_WINAMP "Could not find Winamp!"
+ IDS_ERROR "Error"
+ IDS_WINAMP_NOT_FOUND "Winamp not found"
+ IDS_VISUALIZATIONS "Visualizations"
+ IDS_MEDIA_LIBRARY "Media Library"
+ IDS_NO_SET "no set"
+ IDS_SLOT_X_X "Slot %d (%s)"
+ IDS_COLOR_EDITOR "Color Editor"
+ IDS_SKIN_SETTINGS "Skin Settings\tAlt+C"
+ IDS_WEB_BROWSER "Web Browser\tAlt+X"
+ IDS_ALBUM_ART "Album Art\tAlt+A"
+ IDS_NO_VISUALISATION "No visualization"
+ IDS_SPECTRUM_ANALYZER "Spectrum analyzer"
+ IDS_OSCILLOSCOPE "Oscilloscope"
+ IDS_SKIN_LOAD_FORMAT_OLD
+ "The skin you are trying to load is using an old format.\nAre you sure you want to load this skin? (It might crash!)"
+ IDS_SKIN_LOAD_FORMAT_TOO_RECENT
+ "The skin you are trying to load is using a format that is too recent.\nAre you sure you want to load this skin? (It might crash!)"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_SKIN_LOAD_WARNING "Warning!"
+ IDS_SKIN_LOAD_NOT_SUPPORTED
+ "The skin you are trying to load doesn't seem to be supported."
+ IDS_NO_SKIN_LOADED_ "No skin loaded"
+ IDS_XUITHEME_LOAD "Load"
+ IDS_XUITHEME_SAVE "Save"
+ IDS_MS "ms"
+ IDS_KHZ "kHz"
+ IDS_KBPS "kbps"
+ IDS_USELOCK "Reset window scale to global 'double size' except if it is locked"
+ IDS_ALLLOCKED "All windows remember their scale, disregard global 'double size'"
+ IDS_OPAQUE_FOCUS "Auto opaque on focus"
+ IDS_OPAQUE_HOVER "Auto opaque on hover"
+ IDS_NO_OPACITY "No auto opacity"
+ IDS_LOADING "Loading..."
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "gen_ff.rc2"
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/General/gen_ff/gen_ff.rc2 b/Src/Plugins/General/gen_ff/gen_ff.rc2
new file mode 100644
index 00000000..4c28a37a
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/gen_ff.rc2
@@ -0,0 +1,58 @@
+// Microsoft Visual C++ generated resource script.
+//
+#ifdef APSTUDIO_INVOKED
+ #error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+#include "resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Data
+//
+
+//IDB_MB_TAB_NORMAL RCDATA DISCARDABLE "bitmaps\\mb-unselected.png"
+//IDB_MB_TAB_HILITED RCDATA DISCARDABLE "bitmaps\\mb-hilited.png"
+//IDB_MB_TAB_SELECTED RCDATA DISCARDABLE "bitmaps\\mb-selected.png"
+
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "..\..\..\Winamp/buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,55,0,0
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp General Purpose Plug-in"
+ VALUE "FileVersion", "1,55,0,0"
+ VALUE "InternalName", "Nullsoft Modern Skins Support"
+ VALUE "LegalCopyright", "Copyright © 2003-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "gen_ff.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Src/Plugins/General/gen_ff/gen_ff.sln b/Src/Plugins/General/gen_ff/gen_ff.sln
new file mode 100644
index 00000000..a122851c
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/gen_ff.sln
@@ -0,0 +1,204 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29424.173
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_ff", "gen_ff.vcxproj", "{0A75D6C7-6F14-4032-BBCC-7A234E626A56}"
+ ProjectSection(ProjectDependencies) = postProject
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F} = {DABE6307-F8DD-416D-9DAC-673E2DECB73F}
+ {4F4B5925-2D0B-48DB-BBB0-D321B14EF621} = {4F4B5925-2D0B-48DB-BBB0-D321B14EF621}
+ {FA669B69-C4E6-48F1-B7BF-BB40B6DC0BC0} = {FA669B69-C4E6-48F1-B7BF-BB40B6DC0BC0}
+ {3E0BFA8A-B86A-42E9-A33F-EC294F823F7F} = {3E0BFA8A-B86A-42E9-A33F-EC294F823F7F}
+ {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B} = {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A} = {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}
+ {053B7CED-1A95-4473-8A58-409E93531692} = {053B7CED-1A95-4473-8A58-409E93531692}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bfc", "..\Wasabi\bfc\bfc.vcxproj", "{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tataki", "..\tataki\tataki.vcxproj", "{255B68B5-7EF8-45EF-A675-2D6B88147909}"
+ ProjectSection(ProjectDependencies) = postProject
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F} = {DABE6307-F8DD-416D-9DAC-673E2DECB73F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetypewac", "..\freetypewac\freetypewac.vcxproj", "{2E31944B-64BE-4160-A1CF-7A31A923E204}"
+ ProjectSection(ProjectDependencies) = postProject
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F} = {DABE6307-F8DD-416D-9DAC-673E2DECB73F}
+ {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B} = {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Wasabi", "..\Wasabi\Wasabi.vcxproj", "{3E0BFA8A-B86A-42E9-A33F-EC294F823F7F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsutil", "..\nsutil\nsutil.vcxproj", "{DABE6307-F8DD-416D-9DAC-673E2DECB73F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetype", "..\freetype\freetype.vcxproj", "{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bmp", "..\bmp\bmp.vcxproj", "{3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}"
+ ProjectSection(ProjectDependencies) = postProject
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A} = {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\replicant\zlib\zlib.vcxproj", "{0F9730E4-45DA-4BD2-A50A-403A4BC9751A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jpeg", "..\jpeg\jpeg.vcxproj", "{74EADF6F-F023-4D8C-B03A-5258B192A5E2}"
+ ProjectSection(ProjectDependencies) = postProject
+ {4F4B5925-2D0B-48DB-BBB0-D321B14EF621} = {4F4B5925-2D0B-48DB-BBB0-D321B14EF621}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ijg", "..\ijg\ijg.vcxproj", "{4F4B5925-2D0B-48DB-BBB0-D321B14EF621}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "png", "..\png\png.vcxproj", "{EBA98B5E-F516-47AD-9D97-F5923283C6D8}"
+ ProjectSection(ProjectDependencies) = postProject
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A} = {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}
+ {053B7CED-1A95-4473-8A58-409E93531692} = {053B7CED-1A95-4473-8A58-409E93531692}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "..\libpng\libpng.vcxproj", "{053B7CED-1A95-4473-8A58-409E93531692}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xml", "..\xml\xml.vcxproj", "{4FA2D01A-8932-45BA-9C54-E8247DD2CCAB}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "timer", "..\timer\timer.vcxproj", "{C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0A75D6C7-6F14-4032-BBCC-7A234E626A56}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0A75D6C7-6F14-4032-BBCC-7A234E626A56}.Debug|Win32.Build.0 = Debug|Win32
+ {0A75D6C7-6F14-4032-BBCC-7A234E626A56}.Debug|x64.ActiveCfg = Debug|x64
+ {0A75D6C7-6F14-4032-BBCC-7A234E626A56}.Debug|x64.Build.0 = Debug|x64
+ {0A75D6C7-6F14-4032-BBCC-7A234E626A56}.Release|Win32.ActiveCfg = Release|Win32
+ {0A75D6C7-6F14-4032-BBCC-7A234E626A56}.Release|Win32.Build.0 = Release|Win32
+ {0A75D6C7-6F14-4032-BBCC-7A234E626A56}.Release|x64.ActiveCfg = Release|x64
+ {0A75D6C7-6F14-4032-BBCC-7A234E626A56}.Release|x64.Build.0 = Release|x64
+ {D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Debug|Win32.Build.0 = Debug|Win32
+ {D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Debug|x64.ActiveCfg = Debug|x64
+ {D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Debug|x64.Build.0 = Debug|x64
+ {D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Release|Win32.ActiveCfg = Release|Win32
+ {D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Release|Win32.Build.0 = Release|Win32
+ {D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Release|x64.ActiveCfg = Release|x64
+ {D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Release|x64.Build.0 = Release|x64
+ {255B68B5-7EF8-45EF-A675-2D6B88147909}.Debug|Win32.ActiveCfg = Debug|Win32
+ {255B68B5-7EF8-45EF-A675-2D6B88147909}.Debug|Win32.Build.0 = Debug|Win32
+ {255B68B5-7EF8-45EF-A675-2D6B88147909}.Debug|x64.ActiveCfg = Debug|x64
+ {255B68B5-7EF8-45EF-A675-2D6B88147909}.Debug|x64.Build.0 = Debug|x64
+ {255B68B5-7EF8-45EF-A675-2D6B88147909}.Release|Win32.ActiveCfg = Release|Win32
+ {255B68B5-7EF8-45EF-A675-2D6B88147909}.Release|Win32.Build.0 = Release|Win32
+ {255B68B5-7EF8-45EF-A675-2D6B88147909}.Release|x64.ActiveCfg = Release|x64
+ {255B68B5-7EF8-45EF-A675-2D6B88147909}.Release|x64.Build.0 = Release|x64
+ {2E31944B-64BE-4160-A1CF-7A31A923E204}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2E31944B-64BE-4160-A1CF-7A31A923E204}.Debug|Win32.Build.0 = Debug|Win32
+ {2E31944B-64BE-4160-A1CF-7A31A923E204}.Debug|x64.ActiveCfg = Debug|x64
+ {2E31944B-64BE-4160-A1CF-7A31A923E204}.Debug|x64.Build.0 = Debug|x64
+ {2E31944B-64BE-4160-A1CF-7A31A923E204}.Release|Win32.ActiveCfg = Release|Win32
+ {2E31944B-64BE-4160-A1CF-7A31A923E204}.Release|Win32.Build.0 = Release|Win32
+ {2E31944B-64BE-4160-A1CF-7A31A923E204}.Release|x64.ActiveCfg = Release|x64
+ {2E31944B-64BE-4160-A1CF-7A31A923E204}.Release|x64.Build.0 = Release|x64
+ {3E0BFA8A-B86A-42E9-A33F-EC294F823F7F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3E0BFA8A-B86A-42E9-A33F-EC294F823F7F}.Debug|Win32.Build.0 = Debug|Win32
+ {3E0BFA8A-B86A-42E9-A33F-EC294F823F7F}.Debug|x64.ActiveCfg = Debug|x64
+ {3E0BFA8A-B86A-42E9-A33F-EC294F823F7F}.Debug|x64.Build.0 = Debug|x64
+ {3E0BFA8A-B86A-42E9-A33F-EC294F823F7F}.Release|Win32.ActiveCfg = Release|Win32
+ {3E0BFA8A-B86A-42E9-A33F-EC294F823F7F}.Release|Win32.Build.0 = Release|Win32
+ {3E0BFA8A-B86A-42E9-A33F-EC294F823F7F}.Release|x64.ActiveCfg = Release|x64
+ {3E0BFA8A-B86A-42E9-A33F-EC294F823F7F}.Release|x64.Build.0 = Release|x64
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|Win32.Build.0 = Debug|Win32
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|x64.ActiveCfg = Debug|x64
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|x64.Build.0 = Debug|x64
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|Win32.ActiveCfg = Release|Win32
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|Win32.Build.0 = Release|Win32
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|x64.ActiveCfg = Release|x64
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|x64.Build.0 = Release|x64
+ {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|Win32.Build.0 = Debug|Win32
+ {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|x64.ActiveCfg = Debug|x64
+ {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|x64.Build.0 = Debug|x64
+ {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|Win32.ActiveCfg = Release|Win32
+ {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|Win32.Build.0 = Release|Win32
+ {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|x64.ActiveCfg = Release|x64
+ {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|x64.Build.0 = Release|x64
+ {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Debug|Win32.Build.0 = Debug|Win32
+ {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Debug|x64.ActiveCfg = Debug|x64
+ {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Debug|x64.Build.0 = Debug|x64
+ {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Release|Win32.ActiveCfg = Release|Win32
+ {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Release|Win32.Build.0 = Release|Win32
+ {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Release|x64.ActiveCfg = Release|x64
+ {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Release|x64.Build.0 = Release|x64
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|Win32.Build.0 = Debug|Win32
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|x64.ActiveCfg = Debug|x64
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|x64.Build.0 = Debug|x64
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|Win32.ActiveCfg = Release|Win32
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|Win32.Build.0 = Release|Win32
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|x64.ActiveCfg = Release|x64
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|x64.Build.0 = Release|x64
+ {74EADF6F-F023-4D8C-B03A-5258B192A5E2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {74EADF6F-F023-4D8C-B03A-5258B192A5E2}.Debug|Win32.Build.0 = Debug|Win32
+ {74EADF6F-F023-4D8C-B03A-5258B192A5E2}.Debug|x64.ActiveCfg = Debug|x64
+ {74EADF6F-F023-4D8C-B03A-5258B192A5E2}.Debug|x64.Build.0 = Debug|x64
+ {74EADF6F-F023-4D8C-B03A-5258B192A5E2}.Release|Win32.ActiveCfg = Release|Win32
+ {74EADF6F-F023-4D8C-B03A-5258B192A5E2}.Release|Win32.Build.0 = Release|Win32
+ {74EADF6F-F023-4D8C-B03A-5258B192A5E2}.Release|x64.ActiveCfg = Release|x64
+ {74EADF6F-F023-4D8C-B03A-5258B192A5E2}.Release|x64.Build.0 = Release|x64
+ {4F4B5925-2D0B-48DB-BBB0-D321B14EF621}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4F4B5925-2D0B-48DB-BBB0-D321B14EF621}.Debug|Win32.Build.0 = Debug|Win32
+ {4F4B5925-2D0B-48DB-BBB0-D321B14EF621}.Debug|x64.ActiveCfg = Debug|x64
+ {4F4B5925-2D0B-48DB-BBB0-D321B14EF621}.Debug|x64.Build.0 = Debug|x64
+ {4F4B5925-2D0B-48DB-BBB0-D321B14EF621}.Release|Win32.ActiveCfg = Release|Win32
+ {4F4B5925-2D0B-48DB-BBB0-D321B14EF621}.Release|Win32.Build.0 = Release|Win32
+ {4F4B5925-2D0B-48DB-BBB0-D321B14EF621}.Release|x64.ActiveCfg = Release|x64
+ {4F4B5925-2D0B-48DB-BBB0-D321B14EF621}.Release|x64.Build.0 = Release|x64
+ {EBA98B5E-F516-47AD-9D97-F5923283C6D8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {EBA98B5E-F516-47AD-9D97-F5923283C6D8}.Debug|Win32.Build.0 = Debug|Win32
+ {EBA98B5E-F516-47AD-9D97-F5923283C6D8}.Debug|x64.ActiveCfg = Debug|x64
+ {EBA98B5E-F516-47AD-9D97-F5923283C6D8}.Debug|x64.Build.0 = Debug|x64
+ {EBA98B5E-F516-47AD-9D97-F5923283C6D8}.Release|Win32.ActiveCfg = Release|Win32
+ {EBA98B5E-F516-47AD-9D97-F5923283C6D8}.Release|Win32.Build.0 = Release|Win32
+ {EBA98B5E-F516-47AD-9D97-F5923283C6D8}.Release|x64.ActiveCfg = Release|x64
+ {EBA98B5E-F516-47AD-9D97-F5923283C6D8}.Release|x64.Build.0 = Release|x64
+ {053B7CED-1A95-4473-8A58-409E93531692}.Debug|Win32.ActiveCfg = Debug|Win32
+ {053B7CED-1A95-4473-8A58-409E93531692}.Debug|Win32.Build.0 = Debug|Win32
+ {053B7CED-1A95-4473-8A58-409E93531692}.Debug|x64.ActiveCfg = Debug|x64
+ {053B7CED-1A95-4473-8A58-409E93531692}.Debug|x64.Build.0 = Debug|x64
+ {053B7CED-1A95-4473-8A58-409E93531692}.Release|Win32.ActiveCfg = Release|Win32
+ {053B7CED-1A95-4473-8A58-409E93531692}.Release|Win32.Build.0 = Release|Win32
+ {053B7CED-1A95-4473-8A58-409E93531692}.Release|x64.ActiveCfg = Release|x64
+ {053B7CED-1A95-4473-8A58-409E93531692}.Release|x64.Build.0 = Release|x64
+ {4FA2D01A-8932-45BA-9C54-E8247DD2CCAB}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4FA2D01A-8932-45BA-9C54-E8247DD2CCAB}.Debug|Win32.Build.0 = Debug|Win32
+ {4FA2D01A-8932-45BA-9C54-E8247DD2CCAB}.Debug|x64.ActiveCfg = Debug|x64
+ {4FA2D01A-8932-45BA-9C54-E8247DD2CCAB}.Debug|x64.Build.0 = Debug|x64
+ {4FA2D01A-8932-45BA-9C54-E8247DD2CCAB}.Release|Win32.ActiveCfg = Release|Win32
+ {4FA2D01A-8932-45BA-9C54-E8247DD2CCAB}.Release|Win32.Build.0 = Release|Win32
+ {4FA2D01A-8932-45BA-9C54-E8247DD2CCAB}.Release|x64.ActiveCfg = Release|x64
+ {4FA2D01A-8932-45BA-9C54-E8247DD2CCAB}.Release|x64.Build.0 = Release|x64
+ {FA669B69-C4E6-48F1-B7BF-BB40B6DC0BC0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FA669B69-C4E6-48F1-B7BF-BB40B6DC0BC0}.Debug|Win32.Build.0 = Debug|Win32
+ {FA669B69-C4E6-48F1-B7BF-BB40B6DC0BC0}.Debug|x64.ActiveCfg = Debug|x64
+ {FA669B69-C4E6-48F1-B7BF-BB40B6DC0BC0}.Debug|x64.Build.0 = Debug|x64
+ {FA669B69-C4E6-48F1-B7BF-BB40B6DC0BC0}.Release|Win32.ActiveCfg = Release|Win32
+ {FA669B69-C4E6-48F1-B7BF-BB40B6DC0BC0}.Release|Win32.Build.0 = Release|Win32
+ {FA669B69-C4E6-48F1-B7BF-BB40B6DC0BC0}.Release|x64.ActiveCfg = Release|x64
+ {FA669B69-C4E6-48F1-B7BF-BB40B6DC0BC0}.Release|x64.Build.0 = Release|x64
+ {C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Debug|Win32.Build.0 = Debug|Win32
+ {C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Debug|x64.ActiveCfg = Debug|x64
+ {C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Debug|x64.Build.0 = Debug|x64
+ {C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Release|Win32.ActiveCfg = Release|Win32
+ {C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Release|Win32.Build.0 = Release|Win32
+ {C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Release|x64.ActiveCfg = Release|x64
+ {C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {5A4ED350-80C8-4501-87C2-26BBC67EAD28}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/General/gen_ff/gen_ff.vcxproj b/Src/Plugins/General/gen_ff/gen_ff.vcxproj
new file mode 100644
index 00000000..84fd0c5e
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/gen_ff.vcxproj
@@ -0,0 +1,988 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{0A75D6C7-6F14-4032-BBCC-7A234E626A56}</ProjectGuid>
+ <RootNamespace>gen_ff</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <EmbedManifest>true</EmbedManifest>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnableManifest>false</VcpkgEnableManifest>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <VcpkgInstalledDir>..\..\..\external_dependencies\vcpkg</VcpkgInstalledDir>
+ <VcpkgUseStatic>true</VcpkgUseStatic>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.;..;..\..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;_WINDOWS;_USRDLL;GEN_FF_EXPORTS;NOSVCMGR;_WIN32_IE=0x0A00;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4100;4127;4238;4244;4267;4302;4311;4312;4651;4838;4090;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <ShowIncludes>false</ShowIncludes>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <DelayLoadDLLs>tataki.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.;..;..\..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN64;_DEBUG;_WINDOWS;_USRDLL;GEN_FF_EXPORTS;NOSVCMGR;_WIN32_IE=0x0A00;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4100;4127;4238;4244;4267;4302;4311;4312;4651;4838;4090;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <ShowIncludes>false</ShowIncludes>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <DelayLoadDLLs>tataki.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>.;..;..\..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;_WINDOWS;_USRDLL;GEN_FF_EXPORTS;NOSVCMGR;_WIN32_IE=0x0A00;_CRT_SECURE_NO_WARNINGS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <DisableSpecificWarnings>4100;4127;4238;4244;4267;4302;4311;4312;4651;4838;4090;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <DelayLoadDLLs>tataki.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>true</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>.;..;..\..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN64;NDEBUG;_WINDOWS;_USRDLL;GEN_ff_EXPORTS;NOSVCMGR;_WIN32_IE=0x0A00;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <DisableSpecificWarnings>4100;4127;4238;4244;4267;4302;4311;4312;4651;4838;4090;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <DelayLoadDLLs>tataki.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>true</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\external_dependencies\libmp4v2\libmp4v2.vcxproj">
+ <Project>{efb9b882-6a8b-463d-a8e3-a2807afc5d9f}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\tataki\tataki.vcxproj">
+ <Project>{255b68b5-7ef8-45ef-a675-2d6b88147909}</Project>
+ <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Wasabi\bfc\bfc.vcxproj">
+ <Project>{d0ec862e-dddd-4f4f-934f-b75dc9062dc1}</Project>
+ <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\gen_ml\menu.cpp" />
+ <ClCompile Include="..\..\..\nu\HTMLContainer2.cpp" />
+ <ClCompile Include="..\..\..\nu\listview.cpp" />
+ <ClCompile Include="..\..\..\nu\regexp.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\apiinit.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\application\ifc_messageprocessori.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\api_config.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\api_configi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\api_configx.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\cfglist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\cfgscriptobj.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\config.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\items\attribute.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\items\attrstr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\items\cfgitemi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\items\cfgitemx.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\items\intarray.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\options.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\config\uioptions.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\core\api_core.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\dependency\api_dependent.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\dependency\api_dependentviewer.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\filereader\api_filereader.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\filereader\filereaderapi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\filereader\local\fileread.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\font\bitmapfont.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\font\font.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\font\fontapi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\font\win32\truetypefont_win32.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\api_imgldr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\imggen\grad.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\imggen\osedge.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\imggen\poly.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\imggen\solid.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\imgldr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\imgldrapi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\locales\api_locales.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\locales\api_localesi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\locales\api_localesx.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\locales\localesmgr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\api_maki.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\api_makii.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\api_makix.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\api_makidebug.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\debugapi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\debuggerui.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\debugsymbols.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\disasm.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\jitd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\jitdbreak.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\sdebuggerui.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\sourcecodeline.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\vcpudebug.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\guru.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objcontroller.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objcontrollert.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\core\coreadminobj.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\core\coreobj.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\core\svc_scriptcore.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_browser.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_button.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_checkbox.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_container.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_dropdownlist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_edit.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_group.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_guilist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_guiobject.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_guitree.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_layout.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_menubutton.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_querylist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_rootobj.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_slider.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_text.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_togglebutton.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_treeitem.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_browser.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_button.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_checkbox.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_container.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_dropdownlist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_edit.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_group.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_guilist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_guiobject.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_guitree.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_layout.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_menubutton.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_querylist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_rootobj.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_slider.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_text.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_togglebutton.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_treeitem.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\scripthook.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\guiobj.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\guiobjectx.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\PlaylistScriptObject.cpp">
+ <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)$(TargetName)%(Filename)1.obj</ObjectFileName>
+ <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)$(TargetName)%(Filename)1.obj</ObjectFileName>
+ <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)$(TargetName)%(Filename)1.obj</ObjectFileName>
+ <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)$(TargetName)%(Filename)1.obj</ObjectFileName>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobj.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobjcb.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobjcbi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobjcbx.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobjcontroller.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobject.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobjecti.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobjectx.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sapplication.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sbitlist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\scolor.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\scolormgr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sfile.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sgammagroup.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sgammaset.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\slist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\smap.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\spopup.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sprivate.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sregion.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sxmldoc.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\systemobj.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\wacobj.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\objecttable.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\script.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\scriptmgr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\scriptobj.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\scriptobji.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\scriptobjx.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\script\vcpu.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\api_service.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\servicei.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svccache.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcenum.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcenumbyguid.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcenumt.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_action.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_fileread.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_font.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_imggen.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_imgload.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_minibrowser.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_scriptobj.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_skinfilter.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_textfeed.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_tooltips.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_wndcreate.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_xuiobject.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\svc_enum.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\waservicefactory.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\waservicefactorybase.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\waservicefactoryi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\waservicefactoryt.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\waservicefactorytsingle.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\service\waservicefactoryx.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\api_palette.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\api_skin.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\cursormgr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\feeds\api_textfeed.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\feeds\feedwatch.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\feeds\feedwatcherso.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\feeds\textfeed.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\gammamgr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\groupmgr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\groupwndcreate.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\guitree.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\nakedobject.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\objectactuator.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\regioncache.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skin.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skinapi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skinelem.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skinfilter.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skinfont.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skinitem.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skinparse.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\SkinVersion.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\animlayer.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\button.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\checkbox.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\combobox.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\compbuck2.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\customobject.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\dropdownlist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\edit.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\fx_dmove.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\group.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\groupclickwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\grouplist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\grouptgbutton.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\grouptips.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\guiradiogroup.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\historyeditbox.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\layer.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mb\iebrowser.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mb\mainminibrowser.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mb\mbsvc.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mb\minibrowser.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mb\minibrowserwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mb\xuibrowser.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mouseredir.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\objdirwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\pathpicker.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\pslider.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\sa.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\seqband.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\seqpreamp.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\seqvis.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\spanbar.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\sseeker.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\sstatus.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\stats\statswnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\stats\xuistats.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\svolbar.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\text.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\textbase.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\tgbutton.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\title.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\titlebox.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\wa2\xuiwa2slider.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuiaddparams.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuibookmarklist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuicheckbox.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuicombobox.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuicustomobject.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuidownloadslist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuidropdownlist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuieditbox.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuiframe.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuigradientwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuigrid.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuigroupxfade.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuihideobject.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuihistoryedit.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuilist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuimenu.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuimenuso.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuiobjdirwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuioswndhost.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuipathpicker.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuiprogressgrid.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuiradiogroup.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuirect.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuisendparams.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuistatus.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuitabsheet.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuithemeslist.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuititlebox.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuitree.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuiwndholder.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\api_syscb.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\browsercb.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\corecb.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\playlistcb.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\skincb.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\syscb.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\syscbi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\syscbx.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\timer\timerclient.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\util\selectfile.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\util\systray.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\util\varmgr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wac\compon.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\alphamgr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\animate.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\api_wndmgr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\appcmds.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\autopopup.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\container.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\gc.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\guistatuscb.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\layout.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\msgbox.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\resize.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\skinembed.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\skinwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\snappnt.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\wndmgrapi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\api_window.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\api_wnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\basewnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\contextmenu.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\cursor.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\deactivatemgr.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\di.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\dragitemi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\findobjectcb.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\keyboard.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\paintset.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\popexitcb.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\popexitchecker.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\popup.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\rootwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\virtualwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndapi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\abstractwndhold.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\appbarwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\blankwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\bufferpaintwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\buttbar.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\buttwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\clickwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\editwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\editwndstring.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\embeddedxui.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\foreignwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\framewnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\gradientwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\guiobjwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\labelwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\listwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\oswnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\oswndhost.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\qpaintwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\rootwndholder.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\scbkgwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\scrollbar.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\SelItemList.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\sepwnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\slider.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\status.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\svcwndhold.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\tabsheet.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\tabsheetbar.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\tooltip.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\treewnd.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\typesheet.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\wndholder.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndtrack.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\xml\LoadXML.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\xml\XMLAutoInclude.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\xml\xmlparams.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\xml\xmlparamsi.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\xml\xmlparamsx.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\xml\xmlreader.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\api\xml\xmlwrite.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\bfc\depend.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\bfc\depview.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\bfc\draw\drawpoly.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\bfc\draw\gradient.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\bfc\std_file.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\bfc\util\findopenrect.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\bfc\util\inifile.cpp" />
+ <ClCompile Include="..\..\..\Wasabi\bfc\util\timefmt.cpp" />
+ <ClCompile Include="AlbumArt.cpp" />
+ <ClCompile Include="embedwndguid.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="ff_ipc.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="fsmonitor.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;_NDEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN64;_NDEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="MediaDownloader.cpp" />
+ <ClCompile Include="menuactions.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="minibrowserCOM.cpp" />
+ <ClCompile Include="prefs.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="prefs_about.cpp" />
+ <ClCompile Include="prefs_alpha.cpp" />
+ <ClCompile Include="prefs_colorthemes.cpp" />
+ <ClCompile Include="prefs_font.cpp" />
+ <ClCompile Include="prefs_general.cpp" />
+ <ClCompile Include="servicelink.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="skininfo.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="wa2buckitems.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="wa2cfgitems.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="wa2core.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="wa2coreactions.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="wa2frontend.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="wa2groupdefs.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="wa2playlist.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="wa2pldirobj.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="wa2pledit.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="wa2songticker.cpp" />
+ <ClCompile Include="wa2wndembed.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;GEN_FF_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="WinampConfigScriptObject.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\gen_ml\menu.h" />
+ <CustomBuild Include="..\gen_ml\ml.h">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </CustomBuild>
+ <ClInclude Include="..\..\..\Wasabi\api\apiinit.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\application\ifc_messageprocessori.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\config\api_config.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\config\api_configi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\config\api_configx.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\config\cfglist.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\config\config.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\config\items\attribute.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\config\items\attrstr.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\config\items\cfgitem.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\config\items\cfgitemi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\config\items\cfgitemx.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\config\items\intarray.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\config\uioptions.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\core\api_core.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\core\coreactions.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\dependency\api_dependent.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\dependency\api_dependentviewer.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\filereader\api_filereader.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\filereader\api_readercallback.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\filereader\filereaderapi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\filereader\local\fileread.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\filereader\svc_filereadI.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\font\api_font.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\font\bitmapfont.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\font\font.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\font\fontapi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\font\win32\truetypefont_win32.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\imgldr\api_imgldr.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\imgldr\imggen\grad.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\imgldr\imgldr.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\imgldr\imgldrapi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\imgldr\ImgLoaderEnum.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\locales\api_locales.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\locales\api_localesi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\locales\api_localesx.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\locales\localesmgr.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\api_maki.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\api_makii.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\api_makix.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\debugger\debugsymbols.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\debugger\sdebuggerui.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\core\coreadminobj.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\core\coreobj.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\c_script\h_rootobj.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\c_script\scripthook.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\guiobj.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\guiobject.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\guiobjectx.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\PlaylistScriptObject.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\rootobj.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\rootobject.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\rootobjecti.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\rootobjectx.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\sapplication.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\scolor.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\scolormgr.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\sfile.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\sgammagroup.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\sgammaset.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\sprivate.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\svcwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\sxmldoc.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\timer.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\script\vcpu.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_accessibility.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_accroleserver.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_action.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_droptarget.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_fileread.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_filesel.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_objectdir.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_scriptobj.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_textfeed.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_wndcreate.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\service\waservicefactoryt.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\api_colorthemes.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\api_palette.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\api_skin.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\cursormgr.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\feeds\api_textfeed.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\feeds\ezfeed.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\feeds\textfeed.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\gammamgr.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\group.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\groupmgr.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\groupwndcreate.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\guitree.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skin.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skinapi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skinelem.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skinfilter.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skinfont.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skinitem.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skinparse.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\SkinVersion.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\button.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\combobox.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\compbuck2.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\customobject.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\dropdownlist.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\group.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\grouptgbutton.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\grouptips.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\guiradiogroup.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\historyeditbox.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\layer.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\mb\iebrowser.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\mb\minibrowser.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\mb\minibrowserwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\mouseredir.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\objdirwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\pslider.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\seqband.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\seqpreamp.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\text.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\textbase.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\wa2\xuiwa2slider.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\xuicustomobject.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\xuiframe.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\xuilist.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\xuimenu.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\xuithemeslist.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\xuitree.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\browsercb.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\browsercbi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\metacb.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\playlistcb.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\svccbi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\syscb.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\wndcb.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\timer\api_timer.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\timer\timerclient.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\timer\timermul.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\timer\tmultiplex.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\util\selectfile.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\util\systray.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\util\varmgr.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wac\compon.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\alphamgr.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\animate.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\api_wndmgr.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\appcmds.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\autopopup.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\container.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\gc.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\layout.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\msgbox.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\resize.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\skinembed.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\skinwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\snappnt.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\wndmgrapi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\api_window.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\api_wnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\basewnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\contextmenu.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\cursor.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\deactivatemgr.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\drag.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\dragitem.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\dragitemi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\findobjectcb.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\keyboard.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\minibrowser.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\paintcb.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\platform\win32\bitmap.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\popexitchecker.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\popup.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\resizable.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\rootwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\virtualwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndapi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\abstractwndhold.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\appbarwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\blankwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\buttbar.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\buttwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\editwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\framewnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\gradientwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\guiobjwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\labelwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\listwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\rootwndholder.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\scbkgwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\sepwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\svcwndhold.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\tabsheet.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\tabsheetbar.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\treewnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\virtualhostwnd.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\wndholder.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndtrack.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\xml\LoadXML.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\xml\XMLAutoInclude.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\xml\xmlparams.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\xml\xmlparamsi.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\xml\xmlparamsx.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\xml\xmlreader.h" />
+ <ClInclude Include="..\..\..\Wasabi\api\xml\xmlwrite.h" />
+ <ClInclude Include="..\..\..\Wasabi\bfc\depend.h" />
+ <ClInclude Include="..\..\..\Wasabi\bfc\depview.h" />
+ <ClInclude Include="..\..\..\Wasabi\bfc\util\findopenrect.h" />
+ <CustomBuild Include="..\..\..\Winamp\FRONTEND.H">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Winamp\wa_ipc.h">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </CustomBuild>
+ <ClInclude Include="AlbumArt.h" />
+ <ClInclude Include="api__gen_ff.h" />
+ <ClInclude Include="embedwndguid.h" />
+ <ClInclude Include="main.h" />
+ <ClInclude Include="menuactions.h" />
+ <ClInclude Include="minibrowserCOM.h" />
+ <ClInclude Include="precomp__gen_ff.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="skininfo.h" />
+ <ClInclude Include="wa2buckitems.h" />
+ <ClInclude Include="wa2cfgitems.h" />
+ <ClInclude Include="wa2core.h" />
+ <ClInclude Include="wa2coreactions.h" />
+ <ClInclude Include="wa2frontend.h" />
+ <ClInclude Include="wa2groupdefs.h" />
+ <ClInclude Include="wa2playlist.h" />
+ <ClInclude Include="wa2pldirobj.h" />
+ <ClInclude Include="wa2pledit.h" />
+ <ClInclude Include="wa2songticker.h" />
+ <ClInclude Include="wa2wndembed.h" />
+ <ClInclude Include="wasabicfg.h" />
+ <ClInclude Include="WinampConfigScriptObject.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="gen_ff.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/gen_ff.vcxproj.filters b/Src/Plugins/General/gen_ff/gen_ff.vcxproj.filters
new file mode 100644
index 00000000..149de5c8
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/gen_ff.vcxproj.filters
@@ -0,0 +1,2074 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="AlbumArt.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="embedwndguid.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ff_ipc.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="fsmonitor.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="MediaDownloader.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="menuactions.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="minibrowserCOM.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="prefs.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="prefs_about.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="prefs_alpha.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="prefs_colorthemes.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="prefs_font.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="prefs_general.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="servicelink.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="skininfo.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wa2buckitems.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wa2cfgitems.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wa2core.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wa2coreactions.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wa2frontend.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wa2groupdefs.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wa2playlist.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wa2pldirobj.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wa2pledit.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wa2songticker.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wa2wndembed.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="WinampConfigScriptObject.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\abstractwndhold.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\alphamgr.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\animate.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\animlayer.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\api_config.cpp">
+ <Filter>Source Files\Wasabi\api\config</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\api_configi.cpp">
+ <Filter>Source Files\Wasabi\api\config</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\api_configx.cpp">
+ <Filter>Source Files\Wasabi\api\config</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\core\api_core.cpp">
+ <Filter>Source Files\Wasabi\api\core</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\dependency\api_dependent.cpp">
+ <Filter>Source Files\Wasabi\api\dependency</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\dependency\api_dependentviewer.cpp">
+ <Filter>Source Files\Wasabi\api\dependency</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\filereader\api_filereader.cpp">
+ <Filter>Source Files\Wasabi\api\filereader</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\api_imgldr.cpp">
+ <Filter>Source Files\Wasabi\api\imgldr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\locales\api_locales.cpp">
+ <Filter>Source Files\Wasabi\api\locales</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\locales\api_localesi.cpp">
+ <Filter>Source Files\Wasabi\api\locales</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\locales\api_localesx.cpp">
+ <Filter>Source Files\Wasabi\api\locales</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\api_maki.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\api_makidebug.cpp">
+ <Filter>Source Files\Wasabi\api\script\debugger</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\api_makii.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\api_makix.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\api_palette.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\api_service.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\api_skin.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\api_syscb.cpp">
+ <Filter>Source Files\Wasabi\api\syscb</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\feeds\api_textfeed.cpp">
+ <Filter>Source Files\Wasabi\api\skin\feeds</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\api_window.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\api_wnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\api_wndmgr.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\appbarwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\appcmds.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\items\attribute.cpp">
+ <Filter>Source Files\Wasabi\api\config\items</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\items\attrstr.cpp">
+ <Filter>Source Files\Wasabi\api\config\items</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\autopopup.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\basewnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\font\bitmapfont.cpp">
+ <Filter>Source Files\Wasabi\api\font</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\blankwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\browsercb.cpp">
+ <Filter>Source Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\bufferpaintwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\buttbar.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\button.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\buttwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_browser.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_button.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_checkbox.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_container.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_dropdownlist.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_edit.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_group.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_guilist.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_guiobject.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_guitree.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_layout.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_menubutton.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_querylist.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_rootobj.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_slider.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_text.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_togglebutton.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\c_treeitem.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\items\cfgitemi.cpp">
+ <Filter>Source Files\Wasabi\api\config\items</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\items\cfgitemx.cpp">
+ <Filter>Source Files\Wasabi\api\config\items</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\apiinit.cpp">
+ <Filter>Source Files\Wasabi\api</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\spanbar.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\spopup.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sprivate.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sregion.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\sseeker.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\sstatus.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\stats\statswnd.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets\stats</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\status.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\bfc\std_file.cpp">
+ <Filter>Source Files\Wasabi\bfc</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_action.cpp">
+ <Filter>Source Files\Wasabi\api\service\svcs</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svc_enum.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_fileread.cpp">
+ <Filter>Source Files\Wasabi\api\service\svcs</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_font.cpp">
+ <Filter>Source Files\Wasabi\api\service\svcs</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_imggen.cpp">
+ <Filter>Source Files\Wasabi\api\service\svcs</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_imgload.cpp">
+ <Filter>Source Files\Wasabi\api\service\svcs</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_minibrowser.cpp">
+ <Filter>Source Files\Wasabi\api\service\svcs</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\core\svc_scriptcore.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\core</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_scriptobj.cpp">
+ <Filter>Source Files\Wasabi\api\service\svcs</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_skinfilter.cpp">
+ <Filter>Source Files\Wasabi\api\service\svcs</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_textfeed.cpp">
+ <Filter>Source Files\Wasabi\api\service\svcs</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_tooltips.cpp">
+ <Filter>Source Files\Wasabi\api\service\svcs</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_wndcreate.cpp">
+ <Filter>Source Files\Wasabi\api\service\svcs</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcs\svc_xuiobject.cpp">
+ <Filter>Source Files\Wasabi\api\service\svcs</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svccache.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcenum.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcenumbyguid.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\svcenumt.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\svcwndhold.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\svolbar.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sxmldoc.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\syscb.cpp">
+ <Filter>Source Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\syscbi.cpp">
+ <Filter>Source Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\syscbx.cpp">
+ <Filter>Source Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\systemobj.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\util\systray.cpp">
+ <Filter>Source Files\Wasabi\api\util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\tabsheet.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\tabsheetbar.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\text.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\textbase.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\feeds\textfeed.cpp">
+ <Filter>Source Files\Wasabi\api\skin\feeds</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\tgbutton.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\bfc\util\timefmt.cpp">
+ <Filter>Source Files\Wasabi\bfc\util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\timer\timerclient.cpp">
+ <Filter>Source Files\Wasabi\api\timer</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\title.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\titlebox.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\tooltip.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\treewnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\font\win32\truetypefont_win32.cpp">
+ <Filter>Source Files\Wasabi\api\font\win32</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\typesheet.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\uioptions.cpp">
+ <Filter>Source Files\Wasabi\api\config</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\util\varmgr.cpp">
+ <Filter>Source Files\Wasabi\api\util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\vcpu.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\vcpudebug.cpp">
+ <Filter>Source Files\Wasabi\api\script\debugger</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\virtualwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\wacobj.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\waservicefactory.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\waservicefactorybase.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\waservicefactoryi.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\waservicefactoryt.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\waservicefactorytsingle.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\waservicefactoryx.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndapi.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\wndholder.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\wndmgrapi.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndtrack.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\xml\XMLAutoInclude.cpp">
+ <Filter>Source Files\Wasabi\api\xml</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\xml\xmlparams.cpp">
+ <Filter>Source Files\Wasabi\api\xml</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\xml\xmlparamsi.cpp">
+ <Filter>Source Files\Wasabi\api\xml</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\xml\xmlparamsx.cpp">
+ <Filter>Source Files\Wasabi\api\xml</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\xml\xmlreader.cpp">
+ <Filter>Source Files\Wasabi\api\xml</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\xml\xmlwrite.cpp">
+ <Filter>Source Files\Wasabi\api\xml</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuiaddparams.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuibookmarklist.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mb\xuibrowser.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets\mb</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuicheckbox.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuicombobox.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuicustomobject.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuidownloadslist.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuidropdownlist.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuieditbox.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuiframe.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuigradientwnd.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuigrid.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuigroupxfade.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuihideobject.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuihistoryedit.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuilist.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuimenu.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuimenuso.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuiobjdirwnd.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuioswndhost.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuipathpicker.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuiprogressgrid.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuiradiogroup.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuirect.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuisendparams.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\stats\xuistats.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets\stats</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuistatus.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuitabsheet.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuithemeslist.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuititlebox.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuitree.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\wa2\xuiwa2slider.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets\wa2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\xuiwndholder.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\cfglist.cpp">
+ <Filter>Source Files\Wasabi\api\config</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\cfgscriptobj.cpp">
+ <Filter>Source Files\Wasabi\api\config</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\checkbox.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\clickwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\combobox.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\compbuck2.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wac\compon.cpp">
+ <Filter>Source Files\Wasabi\api\wac</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\config.cpp">
+ <Filter>Source Files\Wasabi\api\config</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\container.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\contextmenu.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\core\coreadminobj.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\core</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\corecb.cpp">
+ <Filter>Source Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\core\coreobj.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\core</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\cursor.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\cursormgr.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\customobject.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\deactivatemgr.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\debugapi.cpp">
+ <Filter>Source Files\Wasabi\api\script\debugger</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\debuggerui.cpp">
+ <Filter>Source Files\Wasabi\api\script\debugger</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\debugsymbols.cpp">
+ <Filter>Source Files\Wasabi\api\script\debugger</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\bfc\depend.cpp">
+ <Filter>Source Files\Wasabi\bfc</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\bfc\depview.cpp">
+ <Filter>Source Files\Wasabi\bfc</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\di.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\disasm.cpp">
+ <Filter>Source Files\Wasabi\api\script\debugger</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\dragitemi.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\bfc\draw\drawpoly.cpp">
+ <Filter>Source Files\Wasabi\bfc\draw</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\dropdownlist.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\edit.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\editwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\editwndstring.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\embeddedxui.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\feeds\feedwatch.cpp">
+ <Filter>Source Files\Wasabi\api\skin\feeds</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\feeds\feedwatcherso.cpp">
+ <Filter>Source Files\Wasabi\api\skin\feeds</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\filereader\local\fileread.cpp">
+ <Filter>Source Files\Wasabi\api\filereader\local</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\filereader\filereaderapi.cpp">
+ <Filter>Source Files\Wasabi\api\filereader</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\findobjectcb.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\bfc\util\findopenrect.cpp">
+ <Filter>Source Files\Wasabi\bfc\util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\font\font.cpp">
+ <Filter>Source Files\Wasabi\api\font</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\font\fontapi.cpp">
+ <Filter>Source Files\Wasabi\api\font</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\foreignwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\framewnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\fx_dmove.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\gammamgr.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\gc.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\imggen\grad.cpp">
+ <Filter>Source Files\Wasabi\api\imgldr\imggen</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\bfc\draw\gradient.cpp">
+ <Filter>Source Files\Wasabi\bfc\draw</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\gradientwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\group.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\groupclickwnd.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\grouplist.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\groupmgr.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\grouptgbutton.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\grouptips.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\groupwndcreate.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\guiobj.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\guiobjectx.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\guiobjwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\guiradiogroup.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\guistatuscb.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\guitree.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\guru.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_browser.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_button.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_checkbox.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_container.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_dropdownlist.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_edit.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_group.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_guilist.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_guiobject.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_guitree.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_layout.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_menubutton.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_querylist.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_rootobj.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_slider.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_text.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_togglebutton.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\h_treeitem.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\historyeditbox.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\nu\HTMLContainer2.cpp">
+ <Filter>Source Files\nu</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mb\iebrowser.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets\mb</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\application\ifc_messageprocessori.cpp">
+ <Filter>Source Files\Wasabi\api\application</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\imgldr.cpp">
+ <Filter>Source Files\Wasabi\api\imgldr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\imgldrapi.cpp">
+ <Filter>Source Files\Wasabi\api\imgldr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\bfc\util\inifile.cpp">
+ <Filter>Source Files\Wasabi\bfc\util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\items\intarray.cpp">
+ <Filter>Source Files\Wasabi\api\config\items</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\jitd.cpp">
+ <Filter>Source Files\Wasabi\api\script\debugger</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\jitdbreak.cpp">
+ <Filter>Source Files\Wasabi\api\script\debugger</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\keyboard.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\labelwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\layer.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\layout.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\nu\listview.cpp">
+ <Filter>Source Files\nu</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\listwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\xml\LoadXML.cpp">
+ <Filter>Source Files\Wasabi\api\xml</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mb\mainminibrowser.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets\mb</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mb\mbsvc.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets\mb</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mb\minibrowser.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets\mb</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mb\minibrowserwnd.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets\mb</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\mouseredir.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\msgbox.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\nakedobject.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objcontroller.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objcontrollert.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\objdirwnd.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\objectactuator.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objecttable.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\config\options.cpp">
+ <Filter>Source Files\Wasabi\api\config</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\imggen\osedge.cpp">
+ <Filter>Source Files\Wasabi\api\imgldr\imggen</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\oswnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\oswndhost.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\paintset.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\pathpicker.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\playlistcb.cpp">
+ <Filter>Source Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\PlaylistScriptObject.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\imggen\poly.cpp">
+ <Filter>Source Files\Wasabi\api\imgldr\imggen</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\popexitcb.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\popexitchecker.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\popup.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\pslider.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\qpaintwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\nu\regexp.cpp">
+ <Filter>Source Files\nu</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\regioncache.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\resize.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobj.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobjcb.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobjcbi.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobjcbx.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobjcontroller.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobject.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobjecti.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\rootobjectx.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\rootwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\rootwndholder.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\sa.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sapplication.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sbitlist.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\scbkgwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\scolor.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\scolormgr.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\locales\localesmgr.cpp">
+ <Filter>Source Files\Wasabi\api\locales</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\script.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\c_script\scripthook.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects\c_script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\scriptmgr.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\scriptobj.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\scriptobji.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\scriptobjx.cpp">
+ <Filter>Source Files\Wasabi\api\script</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\scrollbar.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\sdebuggerui.cpp">
+ <Filter>Source Files\Wasabi\api\script\debugger</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\util\selectfile.cpp">
+ <Filter>Source Files\Wasabi\api\util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\SelItemList.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\sepwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\seqband.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\seqpreamp.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\widgets\seqvis.cpp">
+ <Filter>Source Files\Wasabi\api\skin\widgets</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\service\servicei.cpp">
+ <Filter>Source Files\Wasabi\api\service</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sfile.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sgammagroup.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\sgammaset.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skin.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skinapi.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\syscb\callbacks\skincb.cpp">
+ <Filter>Source Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skinelem.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\skinembed.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skinfilter.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skinfont.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skinitem.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\skinparse.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\skin\SkinVersion.cpp">
+ <Filter>Source Files\Wasabi\api\skin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\skinwnd.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wnd\wndclass\slider.cpp">
+ <Filter>Source Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\slist.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\objects\smap.cpp">
+ <Filter>Source Files\Wasabi\api\script\objects</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\wndmgr\snappnt.cpp">
+ <Filter>Source Files\Wasabi\api\wndmgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\imgldr\imggen\solid.cpp">
+ <Filter>Source Files\Wasabi\api\imgldr\imggen</Filter>
+ </ClCompile>
+ <ClCompile Include="..\gen_ml\menu.cpp">
+ <Filter>Source Files\gen_ml</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Wasabi\api\script\debugger\sourcecodeline.cpp">
+ <Filter>Source Files\Wasabi\api\script\debugger</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="AlbumArt.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="embedwndguid.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="main.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\gen_ml\menu.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="menuactions.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="minibrowserCOM.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="precomp__gen_ff.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="skininfo.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wa2buckitems.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wa2cfgitems.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wa2core.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wa2coreactions.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wa2frontend.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wa2groupdefs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wa2playlist.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wa2pldirobj.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wa2pledit.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wa2songticker.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wa2wndembed.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wasabicfg.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="WinampConfigScriptObject.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\abstractwndhold.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\alphamgr.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\animate.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\config\api_config.h">
+ <Filter>Header Files\Wasabi\api\config</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\config\api_configi.h">
+ <Filter>Header Files\Wasabi\api\config</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\config\api_configx.h">
+ <Filter>Header Files\Wasabi\api\config</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\font\api_font.h">
+ <Filter>Header Files\Wasabi\api\font</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\filereader\api_readercallback.h">
+ <Filter>Header Files\Wasabi\api\filereader</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\feeds\api_textfeed.h">
+ <Filter>Header Files\Wasabi\api\skin\feeds</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\timer\api_timer.h">
+ <Filter>Header Files\Wasabi\api\timer</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\api_wndmgr.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\appbarwnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\appcmds.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\autopopup.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\font\bitmapfont.h">
+ <Filter>Header Files\Wasabi\api\font</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\blankwnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\browsercb.h">
+ <Filter>Header Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\browsercbi.h">
+ <Filter>Header Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\buttbar.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\button.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\buttwnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\config\cfglist.h">
+ <Filter>Header Files\Wasabi\api\config</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\combobox.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\compbuck2.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\config\config.h">
+ <Filter>Header Files\Wasabi\api\config</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\container.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\customobject.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\dropdownlist.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\editwnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\feeds\ezfeed.h">
+ <Filter>Header Files\Wasabi\api\skin\feeds</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\filereader\filereaderapi.h">
+ <Filter>Header Files\Wasabi\api\filereader</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\font\font.h">
+ <Filter>Header Files\Wasabi\api\font</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\font\fontapi.h">
+ <Filter>Header Files\Wasabi\api\font</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\framewnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\gc.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\gradientwnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\group.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\grouptgbutton.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\grouptips.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\guiobjwnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\guiradiogroup.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\c_script\h_rootobj.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\historyeditbox.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\application\ifc_messageprocessori.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\imgldr\imgldr.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\imgldr\imgldrapi.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\imgldr\ImgLoaderEnum.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\labelwnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\layer.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\layout.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\listwnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\xml\LoadXML.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\metacb.h">
+ <Filter>Header Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\mb\minibrowser.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\mb\minibrowserwnd.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\mouseredir.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\msgbox.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\objdirwnd.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\playlistcb.h">
+ <Filter>Header Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\PlaylistScriptObject.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\pslider.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\resize.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\rootobj.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\rootobject.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\rootobjecti.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\rootobjectx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\rootwndholder.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\sapplication.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\scbkgwnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\scolor.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\scolormgr.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\c_script\scripthook.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\debugger\sdebuggerui.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\util\selectfile.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\sepwnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\seqband.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\seqpreamp.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\sfile.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\sgammagroup.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\sgammaset.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skin.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skinapi.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skinelem.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\skinembed.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skinfilter.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skinfont.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skinitem.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\skinparse.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\SkinVersion.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\skinwnd.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\snappnt.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\sprivate.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_accessibility.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_accroleserver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_action.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_droptarget.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_fileread.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\filereader\svc_filereadI.h">
+ <Filter>Header Files\Wasabi\api\filereader</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_filesel.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_objectdir.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_scriptobj.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_textfeed.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\service\svcs\svc_wndcreate.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\svccbi.h">
+ <Filter>Header Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\svcwnd.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\svcwndhold.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\sxmldoc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\syscb.h">
+ <Filter>Header Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\util\systray.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\tabsheet.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\tabsheetbar.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\text.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\textbase.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\feeds\textfeed.h">
+ <Filter>Header Files\Wasabi\api\skin\feeds</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\timer.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\timer\timerclient.h">
+ <Filter>Header Files\Wasabi\api\timer</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\timer\timermul.h">
+ <Filter>Header Files\Wasabi\api\timer</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\timer\tmultiplex.h">
+ <Filter>Header Files\Wasabi\api\timer</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\treewnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\font\win32\truetypefont_win32.h">
+ <Filter>Header Files\Wasabi\api\font\win32</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\config\uioptions.h">
+ <Filter>Header Files\Wasabi\api\config</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\util\varmgr.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\vcpu.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\virtualhostwnd.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\service\waservicefactoryt.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\syscb\callbacks\wndcb.h">
+ <Filter>Header Files\Wasabi\api\syscb\callbacks</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndclass\wndholder.h">
+ <Filter>Header Files\Wasabi\api\wnd\wndclass</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wndmgr\wndmgrapi.h">
+ <Filter>Header Files\Wasabi\api\wndmgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\xml\XMLAutoInclude.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\xml\xmlparams.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\xml\xmlparamsi.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\xml\xmlparamsx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\xml\xmlreader.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\xml\xmlwrite.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\xuicustomobject.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\xuiframe.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\xuilist.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\xuimenu.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\xuithemeslist.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\xuitree.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\wa2\xuiwa2slider.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\keyboard.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\minibrowser.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\paintcb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\popexitchecker.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\popup.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\resizable.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\rootwnd.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\virtualwnd.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndapi.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\wndtrack.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\config\items\intarray.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\locales\localesmgr.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="api__gen_ff.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\api_colorthemes.h">
+ <Filter>Header Files\Wasabi\api\skin</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\core\api_core.h">
+ <Filter>Header Files\Wasabi\api\core</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\dependency\api_dependent.h">
+ <Filter>Header Files\Wasabi\api\dependency</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\dependency\api_dependentviewer.h">
+ <Filter>Header Files\Wasabi\api\dependency</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\filereader\api_filereader.h">
+ <Filter>Header Files\Wasabi\api\filereader</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\imgldr\api_imgldr.h">
+ <Filter>Header Files\Wasabi\api\imgldr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\locales\api_locales.h">
+ <Filter>Header Files\Wasabi\api\locales</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\locales\api_localesx.h">
+ <Filter>Header Files\Wasabi\api\locales</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\locales\api_localesi.h">
+ <Filter>Header Files\Wasabi\api\locales</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\api_maki.h">
+ <Filter>Header Files\Wasabi\api\script</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\api_makii.h">
+ <Filter>Header Files\Wasabi\api\script</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\api_makix.h">
+ <Filter>Header Files\Wasabi\api\script</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\api_palette.h">
+ <Filter>Header Files\Wasabi\api\skin</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\api_skin.h">
+ <Filter>Header Files\Wasabi\api\skin</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\api_window.h">
+ <Filter>Header Files\Wasabi\api\wnd</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\api_wnd.h">
+ <Filter>Header Files\Wasabi\api\wnd</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\apiinit.h">
+ <Filter>Header Files\Wasabi\api</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\config\items\attribute.h">
+ <Filter>Header Files\Wasabi\api\config\items</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\config\items\attrstr.h">
+ <Filter>Header Files\Wasabi\api\config\items</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\basewnd.h">
+ <Filter>Header Files\Wasabi\api\wnd</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\platform\win32\bitmap.h">
+ <Filter>Header Files\Wasabi\api\wnd\platform\win32</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\config\items\cfgitem.h">
+ <Filter>Header Files\Wasabi\api\config\items</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\config\items\cfgitemi.h">
+ <Filter>Header Files\Wasabi\api\config\items</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\config\items\cfgitemx.h">
+ <Filter>Header Files\Wasabi\api\config\items</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wac\compon.h">
+ <Filter>Header Files\Wasabi\api\wac</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\contextmenu.h">
+ <Filter>Header Files\Wasabi\api\wnd</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\core\coreactions.h">
+ <Filter>Header Files\Wasabi\api\core</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\core\coreadminobj.h">
+ <Filter>Header Files\Wasabi\api\script\objects\core</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\core\coreobj.h">
+ <Filter>Header Files\Wasabi\api\script\objects\core</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\cursor.h">
+ <Filter>Header Files\Wasabi\api\wnd</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\cursormgr.h">
+ <Filter>Header Files\Wasabi\api\skin</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\deactivatemgr.h">
+ <Filter>Header Files\Wasabi\api\wnd</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\debugger\debugsymbols.h">
+ <Filter>Header Files\Wasabi\api\script\debugger</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\bfc\depend.h">
+ <Filter>Header Files\Wasabi\bfc</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\bfc\depview.h">
+ <Filter>Header Files\Wasabi\bfc</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\drag.h">
+ <Filter>Header Files\Wasabi\api\wnd</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\dragitemi.h">
+ <Filter>Header Files\Wasabi\api\wnd</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\dragitem.h">
+ <Filter>Header Files\Wasabi\api\wnd</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\filereader\local\fileread.h">
+ <Filter>Header Files\Wasabi\api\filereader\local</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\wnd\findobjectcb.h">
+ <Filter>Header Files\Wasabi\api\wnd</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\bfc\util\findopenrect.h">
+ <Filter>Header Files\Wasabi\bfc\util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\gammamgr.h">
+ <Filter>Header Files\Wasabi\api\skin</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\imgldr\imggen\grad.h">
+ <Filter>Header Files\Wasabi\api\imgldr\imggen</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\group.h">
+ <Filter>Header Files\Wasabi\api\skin</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\groupmgr.h">
+ <Filter>Header Files\Wasabi\api\skin</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\groupwndcreate.h">
+ <Filter>Header Files\Wasabi\api\skin</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\guiobj.h">
+ <Filter>Header Files\Wasabi\api\script\objects</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\guiobjectx.h">
+ <Filter>Header Files\Wasabi\api\script\objects</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\script\objects\guiobject.h">
+ <Filter>Header Files\Wasabi\api\script\objects</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\guitree.h">
+ <Filter>Header Files\Wasabi\api\skin</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Wasabi\api\skin\widgets\mb\iebrowser.h">
+ <Filter>Header Files\Wasabi\api\skin\widgets\mb</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\gen_ml\ml.h">
+ <Filter>Header Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Winamp\wa_ipc.h">
+ <Filter>Header Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Winamp\FRONTEND.H">
+ <Filter>Header Files\Winamp</Filter>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{bf65d618-5e45-4f2a-8125-af87835711e2}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Ressource Files">
+ <UniqueIdentifier>{bbaa79ab-c1cc-4e73-b671-e9532c2313cf}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{076c0d6d-9764-48af-83ce-e1e298abadcc}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi">
+ <UniqueIdentifier>{3ddc66e2-c10a-44eb-846f-dde2fd579af9}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api">
+ <UniqueIdentifier>{ed9da2cf-84b0-4883-8183-5756443f1d45}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\config">
+ <UniqueIdentifier>{428efb3d-499b-4538-b225-59995d0a4ad8}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\skin">
+ <UniqueIdentifier>{711418c8-1bf4-487d-8e5e-55bc545352a3}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\skin\widgets">
+ <UniqueIdentifier>{a935b145-a8e6-4fb1-b6d3-2a7d252c9a51}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\wnd">
+ <UniqueIdentifier>{71c5c868-2d6d-405c-8cb7-76423e1d7c52}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\wnd\wndclass">
+ <UniqueIdentifier>{430dcbf9-48d9-4b4a-ab86-d7d4d6a6d60b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\wac">
+ <UniqueIdentifier>{6d228362-30a9-4c00-a03e-2a09d669b992}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\script">
+ <UniqueIdentifier>{83e1c33a-cf4b-4207-ac1c-87b8755d4ad7}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\script\objects">
+ <UniqueIdentifier>{8520b576-ce2c-469c-86fa-14d0f9763eca}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\script\objects\core">
+ <UniqueIdentifier>{f2411e13-0f08-4b12-a167-2f4aafb392a3}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\syscb">
+ <UniqueIdentifier>{cf9bb71c-7c6e-4425-b0a4-0f5a534db77f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\syscb\callbacks">
+ <UniqueIdentifier>{d148307d-f103-4179-b419-39c6d223d3b1}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\script\debugger">
+ <UniqueIdentifier>{a47af283-0ae4-4855-9719-db7403be60f8}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\bfc">
+ <UniqueIdentifier>{c2af4389-c666-45af-9218-86f2adccdcdb}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\bfc\draw">
+ <UniqueIdentifier>{117e60d7-5011-40d3-b3ec-abdceaa4c72e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\skin\feeds">
+ <UniqueIdentifier>{ebddb0e8-052a-41d9-8506-f61752e88cfa}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\filereader">
+ <UniqueIdentifier>{034c19ed-376c-4107-93e5-ba0861c07235}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\filereader\local">
+ <UniqueIdentifier>{55d69045-d7bf-4a69-b84a-7538dfe6baed}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\bfc\util">
+ <UniqueIdentifier>{f448e746-ba3c-42bb-a0c1-f7e93508834f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\font">
+ <UniqueIdentifier>{2372ff4c-f72f-43de-a65d-ba9f537b2913}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\wndmgr">
+ <UniqueIdentifier>{a657e19a-8af2-4f0b-955c-9ccbae2e77d8}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\imgldr">
+ <UniqueIdentifier>{1f90661a-bc0a-441b-b342-2d6eedf9fb94}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\imgldr\imggen">
+ <UniqueIdentifier>{0ae62a5f-d0c5-4ff6-89ca-ab170103c2bc}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\script\objects\c_script">
+ <UniqueIdentifier>{5ab5bf42-9891-4d5f-a9ff-9ece8a4270c2}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\nu">
+ <UniqueIdentifier>{3d2e3e56-48d8-430f-94de-9b8a57dfe4c9}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\skin\widgets\mb">
+ <UniqueIdentifier>{93fe5f86-d0f9-4c43-8e81-cddae4227244}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\application">
+ <UniqueIdentifier>{584eed9a-47e5-4c37-8bca-a95d75c29f62}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\config\items">
+ <UniqueIdentifier>{bffcb066-b578-490f-aaf9-fbf8aef6d4c4}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\xml">
+ <UniqueIdentifier>{dd59272c-3349-40ef-b44b-7347bbf4392d}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\locales">
+ <UniqueIdentifier>{15a4a353-d120-484d-a13a-6ba08eb013b8}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\util">
+ <UniqueIdentifier>{c56b1f21-e4b6-4135-b990-c5530dd83d03}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\service">
+ <UniqueIdentifier>{b9f8ab37-1686-49b1-b338-ba9dd90c6886}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\gen_ml">
+ <UniqueIdentifier>{339b1b9e-0d18-4483-a452-2d7dac4e9774}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\skin\widgets\stats">
+ <UniqueIdentifier>{c9c62206-3924-43e8-b900-a52671601a0e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\service\svcs">
+ <UniqueIdentifier>{f7c32081-1c3e-4652-8fdc-999024d3abab}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\timer">
+ <UniqueIdentifier>{92bac19f-25cb-4864-ad12-9454ca805370}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\font\win32">
+ <UniqueIdentifier>{bfa00cac-2671-4338-a525-dc2a7a3cb835}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\skin\widgets\wa2">
+ <UniqueIdentifier>{e4c9b2bb-dd6a-4bc2-ad09-ca5df8a0f6b8}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\core">
+ <UniqueIdentifier>{5b8e1124-eb86-4fdb-80b1-e62a9038d935}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Wasabi\api\dependency">
+ <UniqueIdentifier>{d3a01f56-464b-4976-813a-80569bcdac9b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi">
+ <UniqueIdentifier>{e8d5e893-f323-4825-991f-51c02ed78ecd}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api">
+ <UniqueIdentifier>{e0ab39aa-1910-4819-a602-0fdd17d66456}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\wnd">
+ <UniqueIdentifier>{6ef901fe-7701-4453-b9c4-d7472c0de173}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\skin">
+ <UniqueIdentifier>{ff1b723c-3fc3-46c9-8cef-2cc3425816c7}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\skin\widgets">
+ <UniqueIdentifier>{a415d0c3-a60e-464c-81cc-706cb07d84d9}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\skin\widgets\wa2">
+ <UniqueIdentifier>{2a37a25a-a795-41d6-b223-ab458cea036f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\xml">
+ <UniqueIdentifier>{29e11ac1-6f08-4aaa-a395-e3848eb70331}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\wnd\wndclass">
+ <UniqueIdentifier>{5e435b28-0443-4721-8b76-88aa15f8328f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\syscb">
+ <UniqueIdentifier>{1e142ae9-c0c9-48cc-9c21-ff3aa423aa04}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\syscb\callbacks">
+ <UniqueIdentifier>{39f17d69-60a7-4065-b4a4-7c29811564e7}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\service">
+ <UniqueIdentifier>{8d268021-ee46-4bee-9f81-7c6abfc875a4}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\script">
+ <UniqueIdentifier>{e86e6bdd-0733-456f-9887-0255316e7467}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\util">
+ <UniqueIdentifier>{781a8fb4-cac7-4473-a69c-1756a64cfd49}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\config">
+ <UniqueIdentifier>{c861b738-eb90-48e4-968a-772d679f3cc6}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\font">
+ <UniqueIdentifier>{b0ee89d7-6347-4058-8480-871ff274503e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\font\win32">
+ <UniqueIdentifier>{aee2537a-d56d-463e-9f3d-0cb76daf7c94}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\timer">
+ <UniqueIdentifier>{763bb103-bdcd-4a05-be99-8424a41baedc}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\skin\feeds">
+ <UniqueIdentifier>{590fffe6-e7cb-4003-881e-cb8e3de02a0e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\script\objects">
+ <UniqueIdentifier>{94de1687-3b46-432c-b0db-2f3d91b37c79}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\service\svcs">
+ <UniqueIdentifier>{24e3748f-b780-4f9b-b819-c3d885bd2794}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\filereader">
+ <UniqueIdentifier>{aec2a760-6241-4542-9d9d-fd2c87cb86bf}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\wndmgr">
+ <UniqueIdentifier>{76ae14a7-78a1-4352-873a-7ec4c1673336}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\script\debugger">
+ <UniqueIdentifier>{13b72f8c-f0f6-4cdc-a8ae-a9dfee4b3b84}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\script\objects\c_script">
+ <UniqueIdentifier>{8d9f0dc3-353d-4ea1-999b-d0c58e5d8237}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\core">
+ <UniqueIdentifier>{44c64431-48ef-4126-865d-e7eedbe2d502}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\dependency">
+ <UniqueIdentifier>{7ecf8a6f-c16e-4ab5-a085-15df6e952981}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\imgldr">
+ <UniqueIdentifier>{94eb27c8-6d80-4b08-8f0e-36c68aa47651}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\locales">
+ <UniqueIdentifier>{6bbae227-6fd3-40d9-8e81-64146c137948}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\config\items">
+ <UniqueIdentifier>{56124eba-f9ec-4c7b-ab97-d0d84b0e32ed}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\wnd\platform">
+ <UniqueIdentifier>{6f852919-472d-458b-8ac5-5f8d41657372}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\wnd\platform\win32">
+ <UniqueIdentifier>{40ebbca9-2cf3-41fe-bf4b-7265a5d488ca}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\wac">
+ <UniqueIdentifier>{6b36cef2-2356-41af-b817-f508f96d78d5}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\script\objects\core">
+ <UniqueIdentifier>{0291d685-9a9b-485b-9aae-744d4afbde70}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\bfc">
+ <UniqueIdentifier>{1edcd4ab-1ef7-48fb-a49c-35b3a9a3be5c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\filereader\local">
+ <UniqueIdentifier>{a80e512f-2eda-4ae3-978f-9030b568f8da}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\bfc\util">
+ <UniqueIdentifier>{19b8ce8d-6a1f-4eca-8e27-4e84a9be5014}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Winamp">
+ <UniqueIdentifier>{fb9b1379-7d7c-4066-a819-80a2e55dd0d6}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\imgldr\imggen">
+ <UniqueIdentifier>{a9dc66ed-6c31-4fae-a36c-9743ba4a33a3}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Wasabi\api\skin\widgets\mb">
+ <UniqueIdentifier>{70d07248-75c9-493f-b244-fe2e839114d8}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="gen_ff.rc">
+ <Filter>Ressource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/gen_ff_ipc.h b/Src/Plugins/General/gen_ff/gen_ff_ipc.h
new file mode 100644
index 00000000..dd279d8d
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/gen_ff_ipc.h
@@ -0,0 +1,20 @@
+#ifndef _GEN_FF_IPC_H
+#define _GEN_FF_IPC_H
+
+#include "ff_ipc.h"
+
+void ff_ipc_getSkinColor(ff_skincolor *sc);
+void ff_ipc_genSkinBitmap(ff_skinbitmap *sb);
+HBITMAP ff_genwa2skinbitmap();
+HWND ff_ipc_getContentWnd(HWND w);
+
+class ColorThemeMonitor : public SkinCallbackI {
+ public:
+ ColorThemeMonitor();
+ virtual ~ColorThemeMonitor();
+ int skincb_onColorThemeChanged(const wchar_t *colortheme);
+};
+
+extern ColorThemeMonitor *colorThemeMonitor;
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/main.cpp b/Src/Plugins/General/gen_ff/main.cpp
new file mode 100644
index 00000000..728d99a4
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/main.cpp
@@ -0,0 +1,3527 @@
+#include "precomp__gen_ff.h"
+#include <windows.h>
+#include <commctrl.h>
+
+#include "main.h"
+#include "resource.h"
+#include "prefs.h"
+#include "wa2frontend.h"
+#include "wa2groupdefs.h"
+#include "wa2wndembed.h"
+#include "wa2cfgitems.h"
+#include "wa2coreactions.h"
+#include "wa2pledit.h"
+#include "embedwndguid.h"
+#include "gen_ff_ipc.h"
+#include "fsmonitor.h"
+#include <api/wnd/wndclass/foreignwnd.h>
+#include "../winamp/wa_ipc.h"
+#include "../gen_hotkeys/wa_hotkeys.h"
+#include <api/script/objects/c_script/c_group.h>
+#include <api/script/objects/c_script/c_text.h>
+
+#include <api/apiinit.h>
+#include <api/wnd/rootwnd.h>
+#include <api/script/objects/guiobject.h>
+#include <api/core/coreactions.h>
+#include "menuactions.h"
+#include <api/wnd/wndclass/oswndhost.h>
+#include <api/script/scriptobj.h>
+#include <api/service/svcs/svc_wndcreate.h>
+#include <bfc/reentryfilter.h>
+#include <api/skin/skinparse.h>
+#include <api/wndmgr/skinembed.h>
+#include <api/skin/widgets/xuiwndholder.h>
+#include <api/skin/widgets/text.h>
+#include <api/script/scriptmgr.h>
+#include <api/wac/compon.h>
+#include <api/application/version.h>
+#include <bfc/parse/pathparse.h>
+#include <tataki/blending/blending.h>
+#include "skininfo.h"
+#include <api/skin/guitree.h>
+
+#include <bfc/wasabi_std_wnd.h>
+
+#include "wa2core.h"
+#include <api/locales/xlatstr.h>
+
+#include <api/wndmgr/gc.h>
+#include <api/syscb/callbacks/gccb.h>
+#include <api/script/vcpu.h>
+#include <tataki/canvas/bltcanvas.h>
+
+#include "../nu/AutoWide.h"
+#include <shlwapi.h>
+#include <windowsx.h>
+//wtf?
+#define _WAFE_H_
+#define ___HOTAMP3_H___
+#include "../gen_hotkeys/hotkey.h"
+
+int embedCreateProc(embedWindowState *p, embedEnumStruct *parms);
+
+DECLARE_MODULE_SVCMGR;
+
+#define VERSION L"1.55"
+//#define VIDDEBUG
+//#define DEBUG_CAPTURES
+
+#include "../gen_ml/ml_ipc.h"
+librarySendToMenuStruct mainSendTo;
+
+#include "../Agave/Language/api_language.h"
+// wasabi based services for localisation support
+api_language *WASABI_API_LNG = 0;
+HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST;
+static wchar_t szDescription[256];
+
+//-----------------------------------------------------------------------------------------------
+#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
+#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
+
+#define ID_FILE_SHOWLIBRARY 40379
+#define WINAMP_OPTIONS_PREFS 40012
+#define WINAMP_HELP_ABOUT 40041
+#define WINAMP_LIGHTNING_CLICK 40339
+#define WINAMP
+#define UPDATE_EGG 0xC0DE+2
+#define VIEWPORT 0xC0DE+3
+static int DEFERREDCALLBACKMSG;
+static int UPDATEDIALOGBOXPARENTMSG;
+
+//-----------------------------------------------------------------------------------------------
+void config();
+void quit();
+int init();
+void quit_inst();
+void init_inst();
+void ToggleLayout(const wchar_t *containerName);
+void RestoreClassicWinamp(int was_loaded);
+extern "C" winampGeneralPurposePlugin plugin =
+{
+ GPPHDR_VER_U,
+ "nullsoft(gen_ff.dll)",
+ init,
+ config,
+ quit,
+};
+
+//-----------------------------------------------------------------------------------------------
+
+int wantContainerInMenu(Container *cont)
+{
+ wchar_t tmpBuf[96] = {0};
+ GUID g = cont->getGUID();
+ if (WCSCASEEQLSAFE(cont->getId(), L"main")) return 0;
+ if (cont->getNoMenu()) return 0;
+ if (g == pleditWndGuid) return 0;
+ if (g == videoWndGuid) return 0;
+ if (g == avs_guid) return 0;
+ if (g == library_guid) return 0;
+ if (WCSCASEEQLSAFE(cont->getName(), L":componenttitle")) return 0;
+ if (WCSCASEEQLSAFE(cont->getName(), L"Playlist Editor") || WCSCASEEQLSAFE(cont->getName(), L"Playlist") || WCSCASEEQLSAFE(cont->getId(), L"pledit")) return 0;
+ if (WCSCASEEQLSAFE(cont->getName(), L"Video Window") || WCSCASEEQLSAFE(cont->getName(), L"Video") || WCSCASEEQLSAFE(cont->getId(), L"Video")) return 0;
+ if (WCSCASEEQLSAFE(cont->getName(), WASABI_API_LNG->GetStringFromGUIDW(GenMlLangGUID,plugin.hDllInstance,18)) ||
+ WCSCASEEQLSAFE(cont->getName(), L"Media Library") ||
+ WCSCASEEQLSAFE(cont->getId(), L"Library") ||
+ WCSCASEEQLSAFE(cont->getName(),WASABI_API_LNGSTRINGW_BUF(IDS_MEDIA_LIBRARY,tmpBuf,96))) return 0;
+ if (WCSCASEEQLSAFE(cont->getName(), L"AVS") || WCSCASEEQLSAFE(cont->getName(), WASABI_API_LNGSTRINGW(IDS_VISUALIZATIONS)) || WCSCASEEQLSAFE(cont->getName(), L"Vis") || WCSCASEEQLSAFE(cont->getId(), L"Avs") || WCSCASEEQLSAFE(cont->getId(), L"Vis")) return 0;
+ return 1;
+}
+
+
+//-----------------------------------------------------------------------------------------------
+
+api_playlists *AGAVE_API_PLAYLISTS = 0;
+api_playlistmanager *AGAVE_API_PLAYLISTMANAGER = 0;
+api_albumart *AGAVE_API_ALBUMART = 0;
+api_downloadManager *WAC_API_DOWNLOADMANAGER = 0;
+api_colorthemes *WASABI_API_COLORTHEMES = 0;
+api_palette *WASABI_API_PALETTE = 0;
+api_threadpool *WASABI_API_THREADPOOL = 0;
+
+StringW m_lastskin_nam, m_lastskin_dir;
+
+inline int lumidiff(int a, int b) {
+ int r1 = (a & 0xFF0000) >> 16;
+ int r2 = (b & 0xFF0000) >> 16;
+ int g1 = (a & 0xFF00) >> 8;
+ int g2 = (b & 0xFF00) >> 8;
+ int b1 = a & 0xFF;
+ int b2 = b & 0xFF;
+ return MIN((ABS(r1 - r2), ABS(g1 - g2)), ABS(b1 - b2));
+}
+
+static void doplaylistcolors()
+{
+ int interpolate = 0;
+ if (SkinParser::getSkinVersion()*10 < 10) interpolate = 1;
+
+ // update colors
+ int buf[6] = {0};
+ waSetPlColorsStruct s = {0, };
+ extern COLORREF getWindowBackground(COLORREF *);
+ COLORREF windowbackground;
+ buf[5] = getWindowBackground(&windowbackground); // auto inverted
+
+ int need_cols = 1, need_bms = 1;
+
+ if (!m_lastskin_dir.isempty())
+ {
+ StringPathCombine bitmapfilename(m_lastskin_dir, L"pledit.bmp");
+ HANDLE h = CreateFileW(bitmapfilename, 0, 0, 0, OPEN_EXISTING, 0, 0);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(h);
+ need_bms = 0;
+ }
+
+ bitmapfilename = StringPathCombine(m_lastskin_dir, L"pledit.txt");
+ h = CreateFileW(bitmapfilename, 0, 0, 0, OPEN_EXISTING, 0, 0);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(h);
+ need_cols = 0;
+ }
+ }
+
+ if (need_cols)
+ {
+ s.numElems = 6;
+ s.elems = buf;
+
+ // list background
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.background"))
+ buf[2] = SkinColor(L"wasabi.list.background") & 0xFFFFFF;
+ else
+ buf[2] = RGBTOBGR(WASABI_API_SKIN->skin_getBitmapColor(L"wasabi.list.background")) & 0xFFFFFF; // inverted coz coming from bitmap
+
+ // normal text
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.text"))
+ buf[0] = SkinColor(L"wasabi.list.text") & 0xFFFFFF;
+ else
+ buf[0] = SkinColor(L"wasabi.edit.text") & 0xFFFFFF;
+
+ if (interpolate)
+ {
+ int c = buf[0];
+ c = lumidiff(c, buf[2]) < 0x1F ? Blenders::BLEND_AVG(buf[0], 0xFF7F7F7F) : c;
+ c = lumidiff(c, buf[2]) < 0x1F ? Blenders::BLEND_AVG(buf[0], 0xFF101010) : c;
+ buf[0] = c & 0xFFFFFF;
+ }
+
+ COLORREF selected;
+
+ // selected items background
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.text.selected.background"))
+ {
+ selected = SkinColor(L"wasabi.list.text.selected.background");
+ buf[3] = selected;
+ }
+ else
+ {
+ // inverted twice, see bellow
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.item.selected"))
+ selected = RGBTOBGR(SkinColor(L"wasabi.list.item.selected"));
+ else
+ selected = RGBTOBGR(SkinColor(SKINCOLOR_TREE_SELITEMBKG));
+
+ COLORREF col = RGBTOBGR(SkinColor(SKINCOLOR_LIST_COLUMNBKG));
+ int a = MAX((col & 0xFF0000) >> 16, MAX((col & 0xFF00) >> 8, col & 0xFF));
+ col = a < 0x1F ? Blenders::BLEND_AVG(windowbackground, 0xFF000000) : col;
+ int listbkg = RGBTOBGR(buf[2]);
+ selected = lumidiff(selected, listbkg) < 0x2F ? Blenders::BLEND_AVG(windowbackground, 0xFF7F7F7F) : selected;
+ selected = lumidiff(selected, listbkg) < 0x2F ? Blenders::BLEND_AVG(listbkg, 0xFF7F7F7F) : selected;
+ selected = lumidiff(selected, listbkg) < 0x2F ? Blenders::BLEND_AVG(windowbackground, 0xFFF0F0F0) : selected;
+ selected = lumidiff(selected, listbkg) < 0x2F ? Blenders::BLEND_AVG(listbkg, 0xFFF0F0F0) : selected;
+ selected = lumidiff(selected, listbkg) < 0x2F ? Blenders::BLEND_AVG(col, 0xFFF0F0F0) : selected;
+ selected = lumidiff(selected, listbkg) < 0x2F ? Blenders::BLEND_AVG(col, 0xFF101010) : selected;
+ selected = lumidiff(selected, RGBTOBGR(buf[0])) < 0x1F ? Blenders::BLEND_AVG(selected, 0xFF101010) : selected;
+ selected = lumidiff(selected, RGBTOBGR(buf[0])) < 0x1F ? Blenders::BLEND_AVG(selected, 0xFFF0F0F0) : selected;
+ selected &= 0xFFFFFF;
+ buf[3] = RGBTOBGR(selected);
+ }
+
+ // active text
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.text.current"))
+ buf[1] = SkinColor(L"wasabi.list.text.current");
+ else
+ {
+ COLORREF act = Blenders::BLEND_AVG(selected, buf[0]);
+ act = (lumidiff(act, buf[0]) < 0x3F || lumidiff(act, buf[2]) < 0x2F) ? Blenders::BLEND_AVG(buf[2], 0xFFFFFFFF) : act;
+ act = (lumidiff(act, buf[0]) < 0x3F || lumidiff(act, buf[2]) < 0x2F) ? Blenders::BLEND_AVG(buf[2], 0xFF101010) : act;
+ act = (lumidiff(act, buf[0]) < 0x3F || lumidiff(act, buf[2]) < 0x2F) ? Blenders::BLEND_AVG(selected, buf[0]) : act;
+ act = (lumidiff(act, buf[0]) < 0x3F || lumidiff(act, buf[2]) < 0x2F) ? Blenders::BLEND_AVG(selected, buf[2]) : act;
+ act = (lumidiff(act, buf[0]) < 0x3F || lumidiff(act, buf[2]) < 0x2F) ? Blenders::BLEND_AVG(buf[0], buf[2]) : act;
+ buf[1] = act & 0xFFFFFF;
+ }
+ }
+
+ if (need_bms)
+ {
+ BltCanvas c(280, 186);
+
+ c.fillBits(windowbackground); // already inverted
+
+ void blitButtonToCanvas(int w, int h, int state, const wchar_t *overlayelement, int xpos, int ypos, BltCanvas *c);
+
+ blitButtonToCanvas(8, 18, 0, L"wasabi.scrollbar.vertical.grip", 52, 53, &c);
+ blitButtonToCanvas(8, 18, 1, L"wasabi.scrollbar.vertical.grip", 61, 53, &c);
+
+ int xpos, ypos;
+ //w=8,h=29
+ int cols[2];
+ int *fb = (int*)c.getBits() + 280 * 42;
+
+ // inverted colors because going into bitmap
+
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.scrollbar.background.inverted"))
+ cols[0] = RGBTOBGR(SkinColor(L"wasabi.scrollbar.background.inverted"));
+ else
+ {
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.column.empty"))
+ cols[0] = RGBTOBGR(SkinColor(L"wasabi.list.column.empty"));
+ else
+ {
+ COLORREF col = SkinColor(SKINCOLOR_LIST_COLUMNBKG);
+ int a = MAX((col & 0xFF0000) >> 16, MAX((col & 0xFF00) >> 8, col & 0xFF));
+ col = a < 0x1F ? Blenders::BLEND_AVG(windowbackground, 0xFF000000) : col;
+ cols[0] = RGBTOBGR(Blenders::BLEND_AVG(col, 0xFF000000));
+ }
+ }
+
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.border.sunken"))
+ cols[1] = RGBTOBGR(SkinColor(L"wasabi.border.sunken"));
+ else
+ {
+ int a = MAX((windowbackground & 0xFF0000) >> 16, MAX((windowbackground & 0xFF00) >> 8, windowbackground & 0xFF));
+ cols[1] = Blenders::BLEND_AVG(windowbackground, a > 0xE0 ? 0xFF000000 : 0xFFFFFFFF);
+ }
+
+ for (ypos = 42;ypos < 42 + 29; ypos ++)
+ {
+ for (xpos = 36; xpos < 36 + 8; xpos ++)
+ {
+ fb[xpos] = cols[(xpos == 36 || xpos == 36 + 8 - 1)];
+ }
+ fb += 280;
+ }
+
+ extern HBITMAP CreateBitmapDIB(int w, int h, int planes, int bpp, void *data);
+ s.bm = CreateBitmapDIB(280, 186, 1, 32, c.getBits());
+ }
+ if (s.bm || s.elems) SendMessageW(wa2.getMainWindow(), WM_WA_IPC, (WPARAM)&s, IPC_SETPLEDITCOLORS);
+}
+
+static prefsDlgRecW ffPrefsItem;
+
+//-----------------------------------------------------------------------------------------------
+
+// a guid for our app : {4BE592C7-6937-426a-A388-ACF0EBC88E93}
+static const GUID GEN_FREEFORM =
+ { 0x4be592c7, 0x6937, 0x426a, { 0xa3, 0x88, 0xac, 0xf0, 0xeb, 0xc8, 0x8e, 0x93 } };
+
+Wa2Groupdefs *groups;
+static WNDPROC wa_oldWndProc;
+
+Wa2CfgItems *cfgitems=0;
+
+HINSTANCE hInstance = NULL;
+HWND last_dlg_parent = NULL;
+void populateWindowsMenus();
+void unpopulateWindowsMenus();
+void addWindowOptionsToContextMenu(ifc_window *w);
+void removeWindowOptionsFromContextMenu();
+void controlOpacity(int v);
+void controlScaling(double v);
+void customScaling();
+void customOpacity();
+void autoOpacifyHover();
+void autoOpacifyFocus();
+ifc_window *g_controlMenuTarget = NULL;
+HMENU controlmenu = NULL;
+void lockScaling(int lock);
+int ffwindowsitempos = -1;
+int ffoptionstop = -1;
+int ffwoptionstop = -1;
+int ffwindowstop = -1;
+int ffwindowsitempos2 = -1;
+int eqremoved = 0;
+void removeEq();
+void restoreEq();
+int g_timedisplaymode = 0;
+ifc_window *lastFocused = NULL;
+int before_startup_callback = 0;
+void loadExtraColorThemes();
+extern _int last_page;
+int gothrueqmsg = 0;
+void unhookOutputIPC();
+int we_have_ml = 0;
+void checkMlPresent();
+char eggstr[9] = {0};
+int eggstat = 0;
+int eggfallout = 0;
+void initEgg();
+void toggleEgg();
+Layout *lastlayoutegg = NULL;
+int disable_send_visrandom = 0;
+void registerGlobalHotkeys();
+int processGenericHotkey(const char *hk);
+const char *getSkinInfo();
+const wchar_t *getSkinInfoW();
+void controlAppBar(int side);
+void controlAppBarAOT();
+void controlAppBarAH();
+void updateAppBarMenu(ifc_window *w);
+void startFSMonitor();
+void stopFSMonitor();
+void onGoFullscreen();
+void onCancelFullscreen();
+FullScreenMonitor *g_fsmonitor = NULL;
+class Wa5FSCallback : public FSCallback
+{
+public:
+ virtual void onGoFullscreen()
+ {
+ ::onGoFullscreen();
+ }
+ virtual void onCancelFullscreen()
+ {
+ ::onCancelFullscreen();
+ }
+};
+Wa5FSCallback *g_fscallback = NULL;
+int getAOTTempDisable()
+{
+ return g_fsmonitor->isFullScreen();
+}
+
+LRESULT CallWinampWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ return CallWindowProcW(wa_oldWndProc, hwnd, msg, wParam, lParam);
+}
+
+//-----------------------------------------------------------------------------------------------
+BOOL WINAPI dll_main_raw_fn(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ hInstance = hinstDLL;
+ Wasabi::Std::Initialize();
+ return TRUE;
+}
+
+extern "C"
+{
+ void *_pRawDllMain = &dll_main_raw_fn;
+};
+
+__declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ hInstance = hinstDLL;
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------------------------
+// core actions implement "play", "stop", etc. wndEmbedded embed wa2 windows into GUID-based wnds
+//-----------------------------------------------------------------------------------------------
+BEGIN_SERVICES(Winamp2_Svcs);
+DECLARE_SERVICETSINGLE(svc_action, CoreActions);
+DECLARE_SERVICETSINGLE(svc_action, MenuActions);
+DECLARE_SERVICETSINGLE(svc_windowCreate, Wa2WndEmbed);
+END_SERVICES(Winamp2_Svcs, _Winamp2_Svcs);
+
+//-----------------------------------------------------------------------------------------------
+// functions called by the overriden windowproc to create and destroy wndembedders
+//-----------------------------------------------------------------------------------------------
+ifc_window *plWnd = NULL;
+#ifdef MINIBROWSER_SUPPORT
+ifc_window *mbWnd = NULL;
+#endif
+ifc_window *vidWnd = NULL;
+TList<HWND> forcedoffwnds;
+
+int going_freeform = 0;
+int going_fixedform = 0;
+
+wchar_t *INI_FILE = 0, *INI_DIR = 0;
+
+void ToggleLayout(const wchar_t *containerName)
+{
+ Container *c = SkinParser::getContainer(containerName);
+ if (c)
+ {
+ int numLayouts = c->getNumLayouts();
+
+ for (int i = 0;i < numLayouts;i++)
+ {
+ if (c->enumLayout(i) == c->getCurrentLayout())
+ {
+ int nextLayout = (i + 1) % numLayouts;
+ Layout *layout = c->enumLayout(nextLayout);
+ c->switchToLayout(layout->getId());
+ return ;
+ }
+ }
+ }
+}
+
+int updatePl()
+{
+ // find out if this GUID is already shown.
+ WindowHolder *wh = skinEmbedder->getSuitableWindowHolder(pleditWndGuid, NULL, NULL, NULL, 1, -1, 0, 1, -1);
+ if (wh != NULL)
+ {
+ wh->cancelDeferredRemove();
+ GuiObject *go = wh->getRootWndPtr()->getGuiObject();
+ if (go)
+ {
+ Layout *l = go->guiobject_getParentLayout();
+ if (l)
+ {
+ Container *c = l->getParentContainer();
+ if (c)
+ {
+ DebugStringW(L"Container is %s\n", c->getId());
+ SkinEmbedder::cancelDestroyContainer(c);
+ }
+ }
+ }
+ plWnd = wh->getRootWndPtr(); //->getDesktopParent();
+ return 1;
+ }
+ return 0;
+}
+
+int createPl()
+{
+ if (updatePl())
+ {
+ ShowWindow(wa2.getWnd(IPC_GETWND_PE), SW_SHOWNA);
+ return 1;
+ }
+ ReentryFilter f(&wndMsgFilter, IPC_GETWND_PE);
+ if (f.mustLeave()) return 1;
+ plWnd = WASABI_API_WNDMGR->skinwnd_createByGuid(pleditWndGuid, L"resizable_status");
+ if (plWnd != NULL)
+ {
+ plWnd->setVisible(1);
+ }
+ return plWnd != NULL;
+}
+
+static ifc_window *updateEmb(GUID thisguid, embedWindowState *ws)
+{
+ WindowHolder *wh = skinEmbedder->getSuitableWindowHolder(thisguid, NULL, NULL, NULL, 1, -1, 0, 1, -1);
+ if (wh != NULL && !(ws->flags & EMBED_FLAGS_LEGACY_WND))
+ {
+ ifc_window *p = wh->getRootWndPtr(); //->getDesktopParent();
+
+ // p->getGuiScriptObject()->vcpu_setInterface(embeddedWndStateGuid, ws, INTERFACE_GENERICVOIDPTR);
+ ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = (intptr_t)p;
+ return p;
+ }
+ return 0;
+}
+
+static ifc_window *createEmb(embedWindowState *ws, bool startHidden)
+{
+ GUID thisguid = EmbedWndGuid(ws).getGuid();
+ if (thisguid == INVALID_GUID || (ws->flags & EMBED_FLAGS_LEGACY_WND))
+ return 0;
+
+ //thisguid.Data1 = (int)ws->me;
+ ifc_window *update = updateEmb(thisguid, ws);
+ if (update)
+ return update;
+
+ ReentryFilter f(&wndMsgFilter, (intptr_t)ws);
+ if (f.mustLeave())
+ return 0;
+
+ RECT r;
+ if (!GetWindowRect(ws->me, &r))
+ SetRectEmpty(&r);
+
+ ifc_window *p = NULL;
+ if (ws->flags & EMBED_FLAGS_NORESIZE)
+ p = WASABI_API_WNDMGR->skinwnd_createByGuid(thisguid, L"static", 0, NULL, 0, startHidden, NULL);
+ else
+ p = WASABI_API_WNDMGR->skinwnd_createByGuid(thisguid, L"resizable_nostatus", 0, NULL, 0, startHidden, NULL);
+
+ ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = (intptr_t) p;
+ if (p != NULL)
+ {
+ // p->getGuiScriptObject()->vcpu_setInterface(embeddedWndStateGuid, ws, INTERFACE_GENERICVOIDPTR);
+ if (NULL != WASABI_API_APP)
+ WASABI_API_APP->app_unregisterGlobalWindow(p->getDesktopParent()->gethWnd());
+
+ if (!startHidden)
+ p->setVisible(1);
+
+ GuiObject *go = p->getGuiObject();
+ if (go)
+ {
+ Layout *l = go->guiobject_getParentLayout();
+ if (l)
+ {
+ Container *c = l->getParentContainer();
+ if (c)
+ {
+ if (ws->flags & EMBED_FLAGS_NOWINDOWMENU)
+ c->setXmlParam(L"nomenu", L"1");
+ else
+ c->setXmlParam(L"nomenu", L"0");
+ }
+ }
+ }
+ }
+ if (p == NULL)
+ {
+ RECT r;
+ GetWindowRect(ws->me, &r);
+ //////SetWindowPos( ws->me, NULL, r.left - 20000, r.top - 20000, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOZORDER | SWP_NOCOPYBITS );
+ SetWindowPos( ws->me, NULL, r.left, r.top, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOZORDER | SWP_NOCOPYBITS );
+ forcedoffwnds.addItem(ws->me);
+ //if (0 != (WS_VISIBLE & windowStyle))
+ //RedrawWindow(GetDesktopWindow(), &r, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_NOERASE);
+ }
+
+ RedrawWindow(GetDesktopWindow(), &r, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_NOERASE);
+ return p;
+}
+
+#ifdef MINIBROWSER_SUPPORT
+int updateMb()
+{
+ WindowHolder *wh = skinEmbedder->getSuitableWindowHolder(minibrowserWndGuid, NULL, NULL, NULL, 1, -1, 0, 1, -1);
+ if (wh != NULL)
+ {
+ mbWnd = wh->getRootWndPtr(); //->getDesktopParent();
+ ShowWindow(wa2.getWnd(IPC_GETWND_MB), SW_SHOWNA);
+ return 1;
+ }
+ return 0;
+}
+
+int createMb()
+{
+ // see cratePl()
+ if (updateMb()) return 1;
+ ReentryFilter f(&wndMsgFilter, IPC_GETWND_MB);
+ if (f.mustLeave()) return 1;
+ mbWnd = WASABI_API_WNDMGR->skinwnd_createByGuid(minibrowserWndGuid, "resizable_status");
+ if (mbWnd != NULL) mbWnd->setVisible(1);
+ return mbWnd != NULL;
+}
+#endif
+
+static HWND oldVideoWnd;
+static WNDPROC oldVideoWndProc;
+static DWORD WINAPI newVideoWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg == WM_USER + 0x100 && wParam == 1 && lParam)
+ return 0;
+
+ return CallWindowProc(oldVideoWndProc, hwnd, uMsg, wParam, lParam);
+}
+
+int updateVid()
+{
+ WindowHolder *wh = skinEmbedder->getSuitableWindowHolder(videoWndGuid, NULL, NULL, NULL, 1, -1, 0, 1, -1);
+ if (wh != NULL)
+ {
+#ifdef VIDDEBUG
+ DebugString("Video : Host already exists and window already shown in it\n");
+#endif
+ wh->cancelDeferredRemove();
+ GuiObject *go = wh->getRootWndPtr()->getGuiObject();
+ if (go)
+ {
+ Layout *l = go->guiobject_getParentLayout();
+ if (l)
+ {
+ Container *c = l->getParentContainer();
+ if (c)
+ {
+ DebugStringW(L"Container is %s\n", c->getId());
+ SkinEmbedder::cancelDestroyContainer(c);
+ }
+ }
+ }
+ vidWnd = wh->getRootWndPtr(); //->getDesktopParent();
+ return 1;
+ }
+ return 0;
+}
+
+int createVid()
+{
+ ShowWindow(WASABI_API_WND->main_getRootWnd()->gethWnd(), SW_RESTORE);
+ SetForegroundWindow(WASABI_API_WND->main_getRootWnd()->gethWnd());
+
+ if (updateVid())
+ {
+ ShowWindow(wa2.getWnd(IPC_GETWND_VIDEO), SW_SHOWNA);
+ return 1;
+ }
+
+ if (vidWnd == NULL)
+ {
+ ReentryFilter f(&wndMsgFilter, IPC_GETWND_VIDEO);
+ if (f.mustLeave()) return 1;
+#ifdef VIDDEBUG
+ DebugString("Video : Trying to find a host or creating it if needed\n");
+#endif
+ vidWnd = WASABI_API_WNDMGR->skinwnd_createByGuid(videoWndGuid, L"resizable_status");
+ }
+
+ if (vidWnd != NULL)
+ {
+ vidWnd->setVisible(1);
+ }
+ return vidWnd != NULL;
+}
+
+int destroyPl(HWND hwndDlg, int uMsg, WPARAM wParam, LPARAM lParam)
+{
+ ReentryFilter f(&wndMsgFilter, IPC_GETWND_PE);
+ int r = CallWinampWndProc(hwndDlg, uMsg, wParam, lParam);
+ if (f.mustLeave()) return r;
+ if (plWnd != NULL && WASABI_API_WND->rootwndIsValid(plWnd))
+ {
+ WASABI_API_WNDMGR->skinwnd_destroy(plWnd);
+ r = !WASABI_API_WND->rootwndIsValid(plWnd);
+ }
+ else
+ r = !SOM::checkAbortShowHideWindow(pleditWndGuid, 0);
+ if (r)
+ plWnd = NULL;
+ return r;
+}
+
+int destroyEmb(HWND hwndDlg, int uMsg, WPARAM wParam, LPARAM lParam, embedWindowState *ws)
+{
+ ReentryFilter f(&wndMsgFilter, (intptr_t)ws);
+ int r = CallWinampWndProc(hwndDlg, uMsg, wParam, lParam);
+ if (f.mustLeave() || (ws->flags & EMBED_FLAGS_LEGACY_WND)) return r;
+ if (ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] == NULL) return r;
+ if (ws->extra_data[EMBED_STATE_EXTRA_REPARENTING] == 1) return r;
+ ifc_window *w = (ifc_window*)ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND];
+#if 1
+ if (WASABI_API_WND->rootwndIsValid(w))
+ {
+ WASABI_API_WNDMGR->skinwnd_destroy(w);
+ r = !WASABI_API_WND->rootwndIsValid(w);
+ }
+ else
+ {
+ r = !SOM::checkAbortShowHideWindow(embedWndGuidMgr.getGuid(ws), 0);
+ }
+ if (r)
+ ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = NULL;
+#else
+ if (WASABI_API_WND->rootwndIsValid(w)) WASABI_API_WNDMGR->skinwnd_destroy(w);
+ else SOM::checkAbortShowHideWindow(embedWndGuidMgr.getGuid(ws), 0);
+ ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = NULL;
+#endif
+ return r;
+}
+
+#ifdef MINIBROWSER_SUPPORT
+int destroyMb(HWND hwndDlg, int uMsg, WPARAM wParam, LPARAM lParam)
+{
+ ReentryFilter f(&wndMsgFilter, IPC_GETWND_MB);
+ int r = CallWinampWndProc(hwndDlg, uMsg, wParam, lParam);
+ if (f.mustLeave()) return r;
+
+ if (mbWnd != NULL && WASABI_API_WND->rootwndIsValid(mbWnd)) WASABI_API_WNDMGR->skinwnd_destroy(mbWnd);
+ else SOM::checkAbortShowHideWindow(minibrowserWndGuid, 0);
+ mbWnd = NULL;
+ return r;
+}
+#endif
+
+int destroyVid(HWND hwndDlg, int uMsg, WPARAM wParam, LPARAM lParam)
+{
+ ReentryFilter f(&wndMsgFilter, IPC_GETWND_VIDEO);
+ int r = CallWinampWndProc(hwndDlg, uMsg, wParam, lParam);
+
+ if (f.mustLeave()) return r;
+
+ if (vidWnd != NULL && WASABI_API_WND->rootwndIsValid(vidWnd))
+ {
+ WASABI_API_WNDMGR->skinwnd_destroy(vidWnd);
+ r = !WASABI_API_WND->rootwndIsValid(vidWnd);
+ }
+ else
+ r = !SOM::checkAbortShowHideWindow(videoWndGuid, 0);
+
+ if (r)
+ vidWnd = NULL;
+
+ return r;
+}
+
+
+int m_loading_at_startup;
+int m_are_we_loaded;
+
+#define WINAMP_REFRESHSKIN 40291
+#define WINAMP_OPTIONS_EQ 40036
+#define WINAMP_OPTIONS_DSIZE 40165
+#define WINAMP_OPTIONS_ELAPSED 40037
+#define WINAMP_OPTIONS_REMAINING 40038
+
+//-----------------------------------------------------------------------------------------------
+class MainLayoutMonitor : public H_Layout
+{
+ public:
+ MainLayoutMonitor(HWND _w, ScriptObject *o) : H_Layout(o) { hwnd= _w; }
+ void hook_onResize(int x, int y, int w, int h);
+ HWND hwnd;
+};
+
+void MainLayoutMonitor::hook_onResize(int x, int y, int w, int h)
+{
+ PostMessage(wa2.getMainWindow(), WM_WA_IPC, (WPARAM)hwnd, UPDATEDIALOGBOXPARENTMSG);
+}
+
+//-----------------------------------------------------------------------------------------------
+// must be called after switching to a new freeform skin
+// should also be called when the main container changes its visible layout
+//-----------------------------------------------------------------------------------------------
+Layout *GetMainLayout()
+{
+ Container *container = SkinParser::getContainer(L"main");
+ if (container != NULL)
+ {
+ return container->getCurrentLayout();
+ }
+ return 0;
+}
+
+HWND GetMainContainerHWND()
+{
+ Layout *l = GetMainLayout();
+ if (l != NULL)
+ return l->gethWnd();
+
+ return 0;
+}
+static MainLayoutMonitor *mainLayoutMonitor = 0;
+void setDialogBoxesParent()
+{
+ Layout *l = GetMainLayout();
+ if (l != NULL)
+ {
+ HWND hwnd = l->gethWnd();
+ delete mainLayoutMonitor;
+ mainLayoutMonitor = new MainLayoutMonitor(hwnd, l->getScriptObject());
+ wa2.setDialogBoxParent(hwnd);
+ PostMessage(wa2.getMainWindow(), WM_WA_IPC, (WPARAM)hwnd, UPDATEDIALOGBOXPARENTMSG);
+ lastFocused = l;
+ }
+}
+
+static void removeSkinExtension(StringW &skinname)
+{
+ int x = skinname.len() - 4;
+ if (x > 0)
+ {
+ const wchar_t *p = ((const wchar_t *)skinname) + x;
+ if (!_wcsicmp(p, L".zip") || !_wcsicmp(p, L".wal") || !_wcsicmp(p, L".wsz"))
+ skinname.trunc(x);
+ }
+}
+
+extern HWND subWnd, tabwnd;
+extern int subWndId;
+extern int toggle_from_wa2;
+int switching_skin = 0;
+void shutdownFFApi();
+
+
+/*-----------------------------------------------------------------------------------------------
+* Winamp2 message processor
+*/
+
+static void RerouteMessage(MSG *pMsg, ifc_window *wnd)
+{
+ if (NULL == wnd)
+ return;
+
+ HWND hReroute = NULL;
+ if (pMsg->hwnd == GetMainContainerHWND())
+ {
+ hReroute = WASABI_API_WND->main_getRootWnd()->gethWnd();
+ if (NULL != hReroute)
+ {
+ pMsg->hwnd = hReroute;
+ }
+ return;
+ }
+ if (wnd->gethWnd() != pMsg->hwnd)
+ return;
+
+ ifc_window *parent = wnd->getRootParent();
+ if (NULL == parent)
+ return;
+
+ Layout *l = static_cast<Layout *>(parent->getInterface(layoutGuid));
+ if (NULL == l)
+ return;
+
+ Container *c = l->getParentContainer();
+ if (NULL == c)
+ return;
+
+ GUID g = c->getDefaultContent();
+ if (INVALID_GUID == g)
+ return;
+
+ if (g == playerWndGuid)
+ hReroute = wa2.getMainWindow();
+ else if (g == pleditWndGuid)
+ hReroute = wa2.getWnd(IPC_GETWND_PE);
+ else if (g == videoWndGuid)
+ hReroute = wa2.getWnd(IPC_GETWND_VIDEO);
+ else
+ {
+ embedWindowState *ews = embedWndGuidMgr.getEmbedWindowState(g);
+ if (ews)
+ hReroute = ews->me;
+ }
+
+ if (NULL != hReroute)
+ pMsg->hwnd = hReroute;
+}
+
+class WaMessageProccessor : public ifc_messageprocessor
+{
+public:
+ WaMessageProccessor() {}
+ ~WaMessageProccessor(void) {}
+
+public:
+ bool ProcessMessage(MSG *pMsg)
+ {
+ if (WM_KEYDOWN == pMsg->message ||
+ WM_KEYUP == pMsg->message ||
+ WM_SYSKEYDOWN == pMsg->message ||
+ WM_SYSKEYUP == pMsg->message)
+ {
+
+ ifc_window *wnd;
+ HWND h = pMsg->hwnd;
+ do
+ {
+ wnd = WASABI_API_WND->rootWndFromOSHandle(h);
+
+ } while (!wnd && NULL!= (h = GetAncestor(h, GA_PARENT)));
+
+ if (wnd)
+ {
+ if (!wnd->isVirtual())
+ {
+ while (wnd)
+ {
+ const wchar_t *pid = wnd->getId();
+ if (pid && *pid) break;
+ wnd = wnd->getParent();
+ }
+ }
+ if (wnd && wnd->getCurVirtualChildFocus())
+ wnd = wnd->getCurVirtualChildFocus();
+ }
+
+ if (wnd)
+ DebugStringW(L"target wnd 0x%08X, id: %s", wnd, wnd->getId());
+
+ INT keyMsg = -1;
+ switch(pMsg->message)
+ {
+ case WM_KEYDOWN:
+ static int pos;
+ if (toupper((int)pMsg->wParam) == eggstr[pos])
+ {
+ if (!eggstr[++pos])
+ {
+ toggleEgg();
+ pos = 0;
+ }
+ }
+ else pos = 0;
+ keyMsg = (0 != WASABI_API_WND->forwardOnKeyDown(wnd, (int)pMsg->wParam, pMsg->lParam));
+ break;
+ case WM_KEYUP: keyMsg = (wnd && 0 != WASABI_API_WND->forwardOnKeyUp(wnd, (int)pMsg->wParam, pMsg->lParam)); break;
+ case WM_SYSKEYDOWN: keyMsg = ( 0 != WASABI_API_WND->forwardOnSysKeyDown(wnd, (int)pMsg->wParam, pMsg->lParam)); break;
+ case WM_SYSKEYUP: keyMsg = (wnd && 0 != WASABI_API_WND->forwardOnSysKeyUp(wnd, (int)pMsg->wParam, pMsg->lParam)); break;
+
+ }
+ if (-1 != keyMsg)
+ {
+ if (keyMsg > 0)
+ return true;
+
+ RerouteMessage(pMsg, wnd);
+ }
+ }
+ return false;
+ }
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#define CBCLASS WaMessageProccessor
+START_DISPATCH;
+CB(IFC_MESSAGEPROCESSOR_PROCESS_MESSAGE, ProcessMessage)
+END_DISPATCH;
+#undef CBCLASS
+
+static WaMessageProccessor waMessageProcessor;
+
+#define TabCtrl_InsertItemW(hwnd, iItem, pitem) \
+ (int)SNDMSG((hwnd), TCM_INSERTITEMW, (WPARAM)(int)(iItem), (LPARAM)(const TC_ITEMW *)(pitem))
+
+//-----------------------------------------------------------------------------------------------
+void onSkinSwitch()
+{
+ switching_skin = 1;
+ int lastloaded = m_are_we_loaded;
+
+ Wa2WndEmbed::rememberVisibleWindows();
+
+ // get skin name
+ wchar_t buf[MAX_PATH] = {0};
+ wchar_t *p = (wchar_t *) SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)buf, IPC_GETSKINW);
+ {
+ m_lastskin_nam.setValue(p);
+ m_lastskin_dir.setValue(buf);
+
+ StringPathCombine t(m_lastskin_dir, L"skin.xml");
+
+ if (!m_lastskin_nam.isempty()
+ && _waccess(t.getValue(), 0))
+ {
+ t.setValue(m_lastskin_dir);
+ StringW n = m_lastskin_nam;
+ removeSkinExtension(n);
+ t.AppendPath(n);
+ t.AppendPath(L"skin.xml");
+ if (!_waccess(t.getValue(), 0))
+ m_lastskin_dir.AppendPath(n);
+ }
+
+ if (!_waccess(t.getValue(), 0))
+ {
+ if (!m_are_we_loaded) init_inst();
+ else
+ {
+ // load new skin
+ StringW skinname = m_lastskin_nam;
+
+ removeSkinExtension(skinname);
+
+ before_startup_callback = 1;
+ WASABI_API_SKIN->skin_switchSkin(skinname, m_lastskin_dir);
+
+ if (DEFERREDCALLBACKMSG > 65536)
+ PostMessage(wa2.getMainWindow(), WM_WA_IPC, 2, DEFERREDCALLBACKMSG);
+ //embedEnumStruct cs = { embedCreateProc, 0 };
+ //SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&cs, IPC_EMBED_ENUM);
+
+ doplaylistcolors();
+ setDialogBoxesParent();
+ populateWindowsMenus();
+ }
+ }
+ else
+ {
+ going_fixedform = 1;
+ quit_inst();
+ }
+ }
+ if (subWnd != NULL && IsWindow(subWnd)) SendMessageW(subWnd, WM_INITDIALOG, 0, 0);
+
+ if (IsWindow(tabwnd))
+ {
+ if (!m_are_we_loaded)
+ {
+ if (subWndId == 5)
+ {
+ DestroyWindow(subWnd);
+ TabCtrl_SetCurSel(tabwnd,0);
+ _dosetsel(GetParent(tabwnd));
+ }
+
+ if (TabCtrl_GetItemCount(tabwnd) == 5)
+ {
+ TabCtrl_DeleteItem(tabwnd,4);
+ TabCtrl_DeleteItem(tabwnd,3);
+ }
+ }
+ else
+ {
+ if (TabCtrl_GetItemCount(tabwnd) == 3)
+ {
+ TCITEMW item = {0};
+ item.mask=TCIF_TEXT;
+ item.pszText=WASABI_API_LNGSTRINGW(IDS_COLOR_THEMES);
+ TabCtrl_InsertItemW(tabwnd,3,&item);
+ item.pszText=WASABI_API_LNGSTRINGW(IDS_CURRENT_SKIN);
+ TabCtrl_InsertItemW(tabwnd,4,&item);
+ }
+ }
+ }
+
+ if (m_are_we_loaded || lastloaded) // dont call this if going from classic->classic
+ Wa2WndEmbed::restoreVisibleWindows();
+
+ if (m_are_we_loaded && WASABI_API_SYSCB)
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::GC, GarbageCollectCallback::GARBAGECOLLECT);
+
+ if (WASABI_API_APP)
+ {
+ if (m_are_we_loaded) WASABI_API_APP->app_addMessageProcessor(&waMessageProcessor);
+ else WASABI_API_APP->app_removeMessageProcessor(&waMessageProcessor);
+ }
+
+ /* TODO: benski> want to add this, but it's causing a weird crash
+ if (going_fixedform)
+ shutdownFFApi();
+ */
+ switching_skin = 0;
+ going_fixedform = 0;
+ before_startup_callback = 0;
+}
+
+static int embedUpdateColorProc(embedWindowState *p, embedEnumStruct *parms)
+{
+ SendMessageW(p->me, WM_DISPLAYCHANGE, 0, 0);
+ return 0;
+}
+
+int embedCreateProc(embedWindowState *ws, embedEnumStruct *parms)
+{
+ ifc_window *rw = reinterpret_cast<ifc_window*>(ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND]);
+
+ if (!rw && IsWindow(ws->me) && IsWindowVisible(ws->me) && !(ws->flags & EMBED_FLAGS_LEGACY_WND))
+ {
+ ifc_window *windowParent = createEmb(ws, true);
+ if (NULL != windowParent)
+ {
+ GuiObject *uiObject = windowParent->getGuiObject();
+ if (NULL != uiObject)
+ {
+ if (0 != (EMBED_FLAGS_FFCALLBACK & ws->flags) &&
+ NULL != ws->callback)
+ {
+ ws->callback(ws, FFC_CREATEEMBED, (LPARAM)windowParent);
+ }
+
+ Layout *layout = uiObject->guiobject_getParentLayout();
+ if (NULL != layout)
+ {
+ Container *container = layout->getParentContainer();
+ if (NULL != container) container->setVisible(1);
+ else layout->setVisible(1);
+ windowParent->setVisible(1);
+ }
+ }
+ }
+
+ if (NULL == windowParent)
+ ShowWindow(ws->me, SW_HIDE);
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------------------------
+void syncDoubleSize(int loading = 0)
+{
+ if (!cfg_uioptions_uselocks.getValueAsInt()) return ;
+ int isdsize = wa2.isDoubleSize();
+ int i;
+ for (i = 0;i < SkinParser::getNumContainers();i++)
+ {
+ Container *c = SkinParser::enumContainer(i);
+ if (c != NULL)
+ {
+ int j;
+ for (j = 0;j < c->getNumLayouts();j++)
+ {
+ Layout *l = c->enumLayout(j);
+ if (l != NULL)
+ {
+ if (l->isScaleLocked()) continue;
+ l->setRenderRatio(isdsize ? 2.0f : 1.0f);
+ }
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+class syncDisplayModeEnumerator : public FindObjectCallbackI
+{
+public:
+ int findobjectcb_matchObject(ifc_window *object)
+ {
+ ScriptObject *s = NULL;
+ GuiObject *g = object->getGuiObject();
+ if (g)
+ {
+ ScriptObject *_s = g->guiobject_getScriptObject();
+ if (_s)
+ {
+ void *v = _s->vcpu_getInterfaceObject(textGuid, &s);
+ if (v && !s)
+ {
+ (static_cast<Text*>(v))->setTimeDisplayMode(g_timedisplaymode);
+ }
+ }
+ }
+ return 0;
+ }
+};
+
+//-----------------------------------------------------------------------------------------------
+void syncDisplayMode()
+{
+ if (switching_skin) return ;
+ g_timedisplaymode = wa2.getTimeDisplayMode();
+ int i;
+ syncDisplayModeEnumerator enumerator;
+ for (i = 0;i < SkinParser::getNumContainers();i++)
+ {
+ Container *c = SkinParser::enumContainer(i);
+ if (c != NULL)
+ {
+ int j;
+ for (j = 0;j < c->getNumLayouts();j++)
+ {
+ Layout *l = c->enumLayout(j);
+ if (!WASABI_API_WND->rootwndIsValid(l)) continue;
+ l->findWindowByCallback(&enumerator);
+ }
+ }
+ }
+}
+
+static POINT viewPort;
+VOID CALLBACK ViewPortChanged(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ KillTimer(hwnd, idEvent);
+ if (viewPort.x && viewPort.y)
+ {
+ SystemObject::onViewPortChanged(viewPort.x, viewPort.y);
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+// Winamp2 main window subclass
+//-----------------------------------------------------------------------------------------------
+static LRESULT WINAPI wa_newWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static int m_in_skinrefresh;
+
+ if (uMsg == WM_COMMAND && LOWORD(wParam) == WINAMP_REFRESHSKIN)
+ {
+ HWND prefs = wa2.getPreferencesWindow();
+ RECT prefrect = {0};
+ if (prefs)
+ {
+ GetWindowRect(prefs, &prefrect);
+ HWND hOwner = (HWND)(LONG_PTR)GetWindowLongPtrW(prefs, GWLP_HWNDPARENT);
+ if (NULL != hOwner && hOwner != hwndDlg)
+ SetWindowLongPtrW(prefs, GWLP_HWNDPARENT, (LONG_PTR)hwndDlg);
+ }
+ m_in_skinrefresh++;
+ DWORD b = CallWinampWndProc(hwndDlg, uMsg, wParam, lParam);
+ onSkinSwitch();
+ if (m_are_we_loaded) doplaylistcolors();
+ m_in_skinrefresh--;
+ if (prefs && !wa2.getPreferencesWindow())
+ {
+ SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_OPTIONS_PREFS, 0);
+ SetWindowPos(wa2.getPreferencesWindow(), NULL, prefrect.left, prefrect.top, prefrect.right - prefrect.left, prefrect.bottom - prefrect.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE);
+ }
+
+ return b;
+ }
+ if (g_Core)
+ {
+ if (uMsg == WM_WA_IPC && lParam == IPC_CB_MISC) g_Core->gotCallback(wParam);
+#define WINAMP_FILE_REPEAT 40022
+#define WINAMP_FILE_SHUFFLE 40023
+#define WINAMP_FILE_MANUALPLADVANCE 40395
+#define UPDATE_DISPLAY_TIMER 38
+ if (uMsg == WM_TIMER)
+ {
+ if (LOWORD(wParam) == UPDATE_EGG)
+ {
+ for (int i = 0;i < SkinParser::getNumContainers();i++)
+ {
+ Container *cont = SkinParser::enumContainer(i);
+ if (cont->isMainContainer())
+ {
+ Layout *l = cont->getCurrentLayout();
+ if (lastlayoutegg && l != lastlayoutegg)
+ {
+ if (WASABI_API_WND->rootwndIsValid(lastlayoutegg))
+ {
+ lastlayoutegg->updateTransparency();
+ lastlayoutegg->setTransparencyOverride(-1);
+ }
+ }
+ lastlayoutegg = l;
+ int v = (WASABI_API_MEDIACORE->core_getLeftVuMeter(0) + WASABI_API_MEDIACORE->core_getRightVuMeter(0)) / 4;
+ eggfallout -= 4;
+ if (v > eggfallout) eggfallout = v;
+ lastlayoutegg->setTransparencyOverride(255 - eggfallout);
+ break;
+ }
+ }
+ return 0;
+ }
+ if (LOWORD(wParam) == UPDATE_DISPLAY_TIMER + 4)
+ {
+ syncDisplayMode();
+ }
+ if (LOWORD(wParam) == 0xC0DE)
+ {
+ if (!wa2.isVisRunning())
+ {
+ KillTimer(wa2.getMainWindow(), 0xC0DE);
+ KillTimer(wa2.getMainWindow(), 0xC0DE + 1);
+ wa2.toggleVis();
+ }
+ }
+ if (LOWORD(wParam) == 0xC0DE + 1)
+ {
+ KillTimer(wa2.getMainWindow(), 0xC0DE);
+ KillTimer(wa2.getMainWindow(), 0xC0DE + 1);
+ }
+ }
+ if (!my_set && (uMsg == WM_COMMAND || uMsg == WM_SYSCOMMAND) && LOWORD(wParam) == WINAMP_FILE_SHUFFLE)
+ {
+ DWORD v = CallWinampWndProc(hwndDlg, uMsg, wParam, lParam);
+ int shuf = wa2.getShuffle();
+ if (!shuffle.getValueAsInt() != !shuf) shuffle.setValueAsInt(shuf);
+ return v;
+ }
+ if (!my_set && (uMsg == WM_COMMAND || uMsg == WM_SYSCOMMAND) &&
+ (LOWORD(wParam) == WINAMP_FILE_REPEAT) ||
+ (LOWORD(wParam) == WINAMP_FILE_MANUALPLADVANCE))
+ {
+ DWORD v = CallWinampWndProc(hwndDlg, uMsg, wParam, lParam);
+ int rep = wa2.getRepeat();
+ int manadv = wa2.getManualPlaylistAdvance();
+ int _v = (rep && manadv) ? -1 : rep;
+ if (repeat.getValueAsInt() != _v) repeat.setValueAsInt(_v);
+ return v;
+ }
+ if ((uMsg == WM_COMMAND || uMsg == WM_SYSCOMMAND) && LOWORD(wParam) == WINAMP_OPTIONS_DSIZE)
+ {
+ int v = CallWinampWndProc(hwndDlg, uMsg, wParam, lParam);
+ syncDoubleSize();
+ return v;
+ }
+ if ((uMsg == WM_COMMAND || uMsg == WM_SYSCOMMAND) && (LOWORD(wParam) == WINAMP_OPTIONS_ELAPSED || LOWORD(wParam) == WINAMP_OPTIONS_REMAINING))
+ {
+ int v = CallWinampWndProc(hwndDlg, uMsg, wParam, lParam);
+ syncDisplayMode();
+ return v;
+ }
+ }
+ if (m_are_we_loaded)
+ {
+ if (uMsg == WM_COMMAND && LOWORD(wParam) == 40266)
+ {
+ ToggleLayout(L"pledit");
+ return 0;
+ }
+ else if (uMsg == WM_COMMAND && LOWORD(wParam) == 40064)
+ {
+ ToggleLayout(L"main");
+ return 0;
+ }
+ else if (uMsg == WM_CLOSE && wParam == 0xDEADBEEF && lParam == 0xDEADF00D)
+ {
+ //if (/*todo: configurable */ 1)
+ {
+ uMsg = WM_COMMAND;
+ wParam = WINAMP_MAIN_WINDOW;
+ }
+ }
+ else if (uMsg == WM_SETTINGCHANGE)
+ {
+ // used to track viewport changes so we can update
+ // e.g. when removing Win8's side-by-side app mode
+ if (wParam == SPI_SETWORKAREA)
+ {
+ KillTimer(wa2.getMainWindow(), VIEWPORT);
+ viewPort.x = -1;
+ viewPort.y = -1;
+ SetTimer(wa2.getMainWindow(), VIEWPORT, 100, ViewPortChanged);
+ }
+ }
+ else if (uMsg == WM_DISPLAYCHANGE)
+ {
+ DWORD b = CallWinampWndProc(hwndDlg, uMsg, wParam, lParam);
+ if (!m_in_skinrefresh) doplaylistcolors();
+
+ // filter out our internal skin updates
+ if (wParam && lParam)
+ {
+ KillTimer(wa2.getMainWindow(), VIEWPORT);
+ viewPort.x = LOWORD(lParam);
+ viewPort.y = HIWORD(lParam);
+ SetTimer(wa2.getMainWindow(), VIEWPORT, 100, ViewPortChanged);
+ }
+
+ return b;
+ }
+ else if (uMsg == WM_INITMENUPOPUP)
+ {
+ HMENU hmenuPopup = (HMENU) wParam;
+
+ if (hmenuPopup && hmenuPopup == mainSendTo.build_hMenu && mainSendTo.mode == 1)
+ {
+ int IPC_LIBRARY_SENDTOMENU = SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&"LibrarySendToMenu", IPC_REGISTER_WINAMP_IPCMESSAGE);
+ if (IPC_LIBRARY_SENDTOMENU > 65536 && SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&mainSendTo, IPC_LIBRARY_SENDTOMENU) == 0xffffffff)
+ mainSendTo.mode = 2;
+ }
+
+ if(hmenuPopup == wa2.getMenuBarMenu(Winamp2FrontEnd::WA2_MAINMENUBAR_PLAY))
+ {
+ CheckMenuItem((HMENU)wParam, WINAMP_FILE_SHUFFLE, wa2.getShuffle() ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem((HMENU)wParam, WINAMP_FILE_REPEAT, wa2.getRepeat() ? MF_CHECKED : MF_UNCHECKED);
+ }
+
+ if (hmenuPopup == wa2.getPopupMenu() ||
+ hmenuPopup == wa2.getMenuBarMenu(Winamp2FrontEnd::WA2_MAINMENUBAR_OPTIONS) ||
+ hmenuPopup == wa2.getMenuBarMenu(Winamp2FrontEnd::WA2_MAINMENUBAR_WINDOWS))
+ {
+ if (hmenuPopup == wa2.getMenuBarMenu(Winamp2FrontEnd::WA2_MAINMENUBAR_OPTIONS)) {
+ EnableMenuItem(hmenuPopup, WINAMP_OPTIONS_DSIZE,
+ MF_BYCOMMAND | (cfg_uioptions_uselocks.getValueAsInt() ? MF_ENABLED : MF_GRAYED));
+ }
+ if (hmenuPopup == wa2.getPopupMenu()){
+ EnableMenuItem(GetSubMenu(hmenuPopup, 11 + wa2.adjustOptionsPopupMenu(0)), WINAMP_OPTIONS_DSIZE,
+ MF_BYCOMMAND | (cfg_uioptions_uselocks.getValueAsInt() ? MF_ENABLED : MF_GRAYED));
+ }
+
+ populateWindowsMenus();
+
+ if ((HMENU)wParam == wa2.getPopupMenu())
+ {
+ for (int i = 0;i < SkinParser::getNumContainers();i++)
+ {
+ Container *cont = SkinParser::enumContainer(i);
+ if (!_wcsicmp(cont->getId(), L"main"))
+ {
+ CheckMenuItem((HMENU)wParam, WINAMP_MAIN_WINDOW, cont->isVisible() ? MF_CHECKED : MF_UNCHECKED);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if (uMsg == WM_SETFOCUS)
+ {
+ if (m_are_we_loaded && !switching_skin)
+ {
+ Container *c = SkinParser::getContainer(L"main");
+ if (c)
+ {
+ Layout *l = c->enumLayout(0);
+ if (l) l->setFocus();
+ }
+ return 1;
+ }
+ }
+ else if (uMsg == WM_WA_IPC)
+ {
+ if (lParam == DEFERREDCALLBACKMSG && DEFERREDCALLBACKMSG > 65536)
+ {
+ if (wParam == 1)
+ {
+ setDialogBoxesParent();
+ return 1;
+ }
+ else if (wParam == 2)
+ {
+ // embed the windows that are currently visible because at the time the window were originally shown,
+ // we hadn't been loaded yet
+ // but then again, we might if it's only a switch skin and not a app load, so let's check anyway
+
+ populateWindowsMenus();
+
+ doplaylistcolors();
+
+ if (plWnd == NULL && wa2.isWindowVisible(IPC_GETWND_PE))
+ if (!createPl()) wa2.setWindowVisible(IPC_GETWND_PE, 0);
+
+#ifdef MINIBROWSER_SUPPORT
+ if (mbWnd == NULL && wa2.isWindowVisible(IPC_GETWND_MB))
+ if (!createMb()) wa2.setWindowVisible(IPC_GETWND_MB, 0);
+#endif
+ if (vidWnd == NULL && wa2.isWindowVisible(IPC_GETWND_VIDEO))
+ if (!createVid()) wa2.setWindowVisible(IPC_GETWND_VIDEO, 0);
+
+ embedEnumStruct cs = { embedCreateProc, 0 };
+ SendMessageW(hwndDlg, WM_WA_IPC, (WPARAM)&cs, IPC_EMBED_ENUM);
+
+ for (int i = 0;i < SkinParser::getNumContainers();i++)
+ {
+ Container *cont = SkinParser::enumContainer(i);
+ if (!_wcsicmp(cont->getId(), L"main"))
+ {
+ for (int j = 0;j < cont->getNumLayouts();j++)
+ {
+ Layout *l = cont->enumLayout(j);
+ if (l && l->isVisible())
+ {
+ SetFocus(l->gethWnd());
+ break;
+ }
+ }
+ }
+ }
+
+ Crossfader::onOutputChanged();
+
+ extern int make_sure_library_is_here_at_startup;
+ if (make_sure_library_is_here_at_startup)
+ SendMessageW(wa2.getMainWindow(), WM_COMMAND, ID_FILE_SHOWLIBRARY, 0);
+ make_sure_library_is_here_at_startup = 0;
+
+ before_startup_callback = 0;
+
+ registerGlobalHotkeys();
+
+ // force a title update since it's not always correct
+ // if gen_ml hasn't loaded fully when we're loading
+ if (wa2.isPlaying())
+ g_Core->gotCallback(IPC_CB_MISC_TITLE, 2);
+ return 1;
+ }
+ }
+ else if (lParam == UPDATEDIALOGBOXPARENTMSG && UPDATEDIALOGBOXPARENTMSG > 65536)
+ {
+ wa2.updateDialogBoxParent((HWND)wParam);
+ }
+ else switch (lParam)
+ {
+ case IPC_GETSKININFO:
+ return (LRESULT)getSkinInfo();
+ case IPC_GETSKININFOW:
+ return (LRESULT)getSkinInfoW();
+ case IPC_SHOW_NOTIFICATION:
+ return SystemObject::onShowNotification();
+ case IPC_CB_VISRANDOM:
+ {
+ int v = wParam;
+ extern _bool visrandom;
+ if (!!v == !!visrandom.getValueAsInt()) break;
+ disable_send_visrandom = 1;
+ visrandom.setValueAsInt(v);
+ disable_send_visrandom = 0;
+ break;
+ }
+ case IPC_CB_OUTPUTCHANGED:
+ Crossfader::onOutputChanged();
+ break;
+
+ case IPC_CB_ONTOGGLEAOT:
+ {
+ if ((WPARAM)cfg_options_alwaysontop.getValueAsInt() != wParam)
+ cfg_options_alwaysontop.setValueAsInt(wParam);
+ break;
+ }
+
+ case IPC_SETIDEALVIDEOSIZE:
+ {
+ wa2.setIdealVideoSize(HIWORD(wParam), LOWORD(wParam));
+ break;
+ }
+ // this is where we detect that wa2 wants to open one of its windows (thru popup menu, button, whatever)
+ // when this happens, we create a freeform wndembedder if one doesn't already exist. that embedder will
+ // reparent and resize the wa2 window on its own. when we return, winamp then shows the HWND inside our frame
+ // as it would show the HWND as a popup normally.
+ case IPC_CB_ONSHOWWND:
+ switch (wParam)
+ {
+ case IPC_CB_WND_PE:
+ if (!createPl()) return 0;
+ break;
+#ifdef MINIBROWSER_SUPPORT
+ case IPC_CB_WND_MB:
+ if (!createMb()) return 0;
+ break;
+#endif
+ case IPC_CB_WND_VIDEO:
+#ifdef VIDDEBUG
+ DebugString("Video : Got IPC_ONSHOW\n");
+#endif
+ if (!createVid())
+ {
+#ifdef VIDDEBUG
+ DebugString("Video : SHOW was cancelled by script\n");
+#endif
+ return 0;
+ }
+ break;
+ default:
+ DebugStringW(L"embedWnd : Got IPC_ONSHOW\n");
+ if (IsWindow((HWND)wParam))
+ {
+ HWND hTarget = (HWND)wParam;
+ embedWindowState *ws = (embedWindowState*)GetWindowLongPtrW(hTarget, GWLP_USERDATA);
+ if (ws && ws->me == hTarget)
+ {
+ GUID thisguid = EmbedWndGuid(ws).getGuid();
+ if (INVALID_GUID == thisguid || NULL == updateEmb(thisguid, ws))
+ {
+ ifc_window *windowParent = createEmb(ws, true);
+ if (NULL != windowParent)
+ {
+ GuiObject *uiObject = windowParent->getGuiObject();
+ if (NULL != uiObject)
+ {
+ if (0 != (EMBED_FLAGS_FFCALLBACK & ws->flags) &&
+ NULL != ws->callback)
+ {
+ ws->callback(ws, FFC_CREATEEMBED, (LPARAM)windowParent);
+ }
+
+ Layout *layout = uiObject->guiobject_getParentLayout();
+ if (NULL != layout)
+ {
+ Container *container = layout->getParentContainer();
+ if (NULL != container) container->setVisible(1);
+ else layout->setVisible(1);
+ windowParent->setVisible(1);
+ }
+ }
+
+ }
+ return (NULL != windowParent);
+ }
+ }
+ }
+ break;
+ }
+ break;
+ // here we do the reverse, we detect that wa2 wants to close one of its windows, so we destroy our window
+ // embedder (it will reparent the wa2 window back to its former parent and resize it back to where it was
+ // on its own). when we return, winamp then hides the window.
+
+ // NOTE! because of this, there might be a split second where the window is seen on the screen as a popup
+ // after you closed the window (this won't happen for static containers [ie: pledit/video in mmd3] since
+ // they are hidden rather than destroyed). this can be fixed in the future
+ case IPC_CB_ONHIDEWND:
+ switch (wParam)
+ {
+ case IPC_CB_WND_PE:
+ destroyPl(hwndDlg, uMsg, wParam, lParam);
+ break;
+#ifdef MINIBROWSER_SUPPORT
+ case IPC_CB_WND_MB:
+ return destroyMb(hwndDlg, uMsg, wParam, lParam);
+#endif
+ case IPC_CB_WND_VIDEO:
+#ifdef VIDDEBUG
+ DebugString("Video : Got IPC_ONHIDE\n");
+#endif
+ return destroyVid(hwndDlg, uMsg, wParam, lParam);
+ default:
+ DebugStringW(L"embedWnd : Got IPC_ONHIDE\n");
+ if (IsWindow((HWND)wParam))
+ {
+ HWND h = (HWND)wParam;
+ embedWindowState *ws = (embedWindowState *)GetWindowLongPtrW(h, GWLP_USERDATA);
+ if (ws) return destroyEmb(hwndDlg, uMsg, wParam, lParam, ws);
+ }
+ break;
+ }
+ break;
+ case IPC_FF_ISMAINWND:
+ {
+ for (int i = 0;i < SkinParser::getNumContainers();i++)
+ {
+ Container *cont = SkinParser::enumContainer(i);
+ if (!_wcsicmp(cont->getId(), L"main"))
+ {
+ for (int j = 0;j < cont->getNumLayouts();j++)
+ {
+ if (cont->enumLayout(j)->gethWnd() == (HWND)wParam) return 1;
+ }
+ break;
+ }
+ }
+ return 0;
+ }
+ case IPC_FF_GETCONTENTWND:
+ return (LRESULT)ff_ipc_getContentWnd((HWND)wParam);
+ case IPC_FF_GETSKINCOLOR:
+ ff_ipc_getSkinColor((ff_skincolor*)wParam);
+ return 1;
+ case IPC_FF_GENSKINBITMAP:
+ ff_ipc_genSkinBitmap((ff_skinbitmap*)wParam);
+ return 1;
+ case IPC_FF_NOTIFYHOTKEY:
+ if (processGenericHotkey((const char *)wParam)) return 0; // prevent gen_hotkey from processing the hotkey
+ return 1; // let gen_hotkey process the hotkey
+ case IPC_GET_GENSKINBITMAP:
+ if (m_are_we_loaded)
+ {
+ if (wParam == 0)
+ {
+ if (m_lastskin_dir[0])
+ {
+ HBITMAP bm;
+ wchar_t bitmapfilename[MAX_PATH] = {0};
+ PathCombineW(bitmapfilename, m_lastskin_dir, L"genex.bmp");
+ bm = (HBITMAP)LoadImageW(NULL, bitmapfilename, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
+ if (bm) return (LRESULT)bm;
+ }
+ return (LRESULT)ff_genwa2skinbitmap();
+ }
+ else if (wParam == 4)
+ {
+ // TODO need to make sure we're covering everything needed for all of this!!
+ int buf[6] = {0};
+ // active text
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.text.current"))
+ buf[1] = SkinColor(L"wasabi.list.text.current");
+ /*else
+ {
+ COLORREF act = Blenders::BLEND_AVG(selected, buf[0]);
+ act = (lumidiff(act, buf[0]) < 0x3F || lumidiff(act, buf[2]) < 0x2F) ? Blenders::BLEND_AVG(buf[2], 0xFFFFFFFF) : act;
+ act = (lumidiff(act, buf[0]) < 0x3F || lumidiff(act, buf[2]) < 0x2F) ? Blenders::BLEND_AVG(buf[2], 0xFF101010) : act;
+ act = (lumidiff(act, buf[0]) < 0x3F || lumidiff(act, buf[2]) < 0x2F) ? Blenders::BLEND_AVG(selected, buf[0]) : act;
+ act = (lumidiff(act, buf[0]) < 0x3F || lumidiff(act, buf[2]) < 0x2F) ? Blenders::BLEND_AVG(selected, buf[2]) : act;
+ act = (lumidiff(act, buf[0]) < 0x3F || lumidiff(act, buf[2]) < 0x2F) ? Blenders::BLEND_AVG(buf[0], buf[2]) : act;
+ buf[1] = act & 0xFFFFFF;
+ }*/
+ return buf[1];
+ }
+ }
+ break;
+ case IPC_FF_ONCOLORTHEMECHANGED:
+ {
+ embedEnumStruct cs = { embedUpdateColorProc, 0 };
+ SendMessageW(hwndDlg, WM_WA_IPC, (WPARAM)&cs, IPC_EMBED_ENUM);
+ if (wParam != 0xf00d) doplaylistcolors();
+ }
+ break;
+ case IPC_PLAYLIST_MODIFIED:
+ {
+ Wa2PlaylistEditor::_onPlaylistModified();
+ }
+ break;
+ }
+ }
+ else if (uMsg == WM_COMMAND && (LOWORD(wParam) == 40144 || LOWORD(wParam) == 40148))
+ {
+ // seek left/right, we need to disable them if we are in a menu, because this is a
+ // plugin (ie: milkdrop) sending us the command manually as a forward rather than
+ // sending us the WM_KEY* directly
+ if (WASABI_API_WND->isKeyboardLocked()) return 0;
+ }
+ else if ((uMsg == WM_COMMAND || uMsg == WM_SYSCOMMAND) && LOWORD(wParam) >= 43000 && LOWORD(wParam) < ffwindowstop)
+ {
+ int id = LOWORD(wParam) - 43000;
+
+ int n = SkinParser::getNumContainers();
+ if (id < n)
+ {
+ Container *cont = SkinParser::enumContainer(id);
+ if (cont) cont->toggle();
+ return 1;
+ }
+ id -= n;
+
+ n = WASABI_API_WNDMGR->autopopup_getNumGuids();
+ if (id < n)
+ {
+ GUID guid = WASABI_API_WNDMGR->autopopup_enumGuid(id);
+ if (guid != INVALID_GUID)
+ WASABI_API_WNDMGR->skinwnd_toggleByGuid(guid);
+ return 1;
+ }
+ id -= n;
+
+ n = WASABI_API_WNDMGR->autopopup_getNumGroups();
+ if (id < n)
+ {
+ const wchar_t *gid = WASABI_API_WNDMGR->autopopup_enumGroup(id);
+ if (gid && *gid)
+ WASABI_API_WNDMGR->skinwnd_toggleByGroupId(gid);
+ return 1;
+ }
+
+ /* for (int c=0;c<SkinParser::getNumContainers();c++) {
+ Container *cont = SkinParser::enumContainer(c);
+ if (cont && wantContainerInMenu(cont)) {
+ if (cont->getName() == NULL) continue;
+ if (id == 0) {
+ if (cont)
+ cont->toggle();
+ return 1;
+ }
+ id--;
+ }
+ }
+ int n = WASABI_API_WNDMGR->autopopup_getNumGuids();
+ for (c=0;c<n;c++) {
+ GUID guid = WASABI_API_WNDMGR->autopopup_enumGuid(c);
+ const char *groupdesc = WASABI_API_WNDMGR->autopopup_enumGuidDescription(c);
+ if (guid != INVALID_GUID && groupdesc && *groupdesc) {
+ if (id == 0) {
+ WASABI_API_WNDMGR->skinwnd_toggleByGuid(guid);
+ return 1;
+ }
+ id--;
+ }
+ }
+ n = WASABI_API_WNDMGR->autopopup_getNumGroups();
+ for (c=0;c<n;c++) {
+ const char *gid = WASABI_API_WNDMGR->autopopup_enumGroup(c);
+ const char *groupdesc = WASABI_API_WNDMGR->autopopup_enumGroupDescription(c);
+ if (id && groupdesc && *gid && *groupdesc) {
+ if (id == 0) {
+ WASABI_API_WNDMGR->skinwnd_toggleByGroupId(gid);
+ return 1;
+ }
+ id--;
+ }
+ }*/
+ return 0;
+ }
+ else if ((uMsg == WM_COMMAND || uMsg == WM_SYSCOMMAND) && LOWORD(wParam) >= 44000 && LOWORD(wParam) < ffoptionstop)
+ {
+ int id = LOWORD(wParam);
+ MenuActions::toggleOption(id - 44000);
+ }
+ else if ((uMsg == WM_COMMAND || uMsg == WM_SYSCOMMAND) && LOWORD(wParam) >= 44500 && LOWORD(wParam) < 45000)
+ {
+ int id = LOWORD(wParam) - 44500;
+ WASABI_API_SKIN->colortheme_setColorSet(WASABI_API_SKIN->colortheme_enumColorSet(id));
+ }
+ else if ((uMsg == WM_COMMAND || uMsg == WM_SYSCOMMAND) && LOWORD(wParam) >= 42000 && LOWORD(wParam) < ffwoptionstop)
+ {
+ int id = LOWORD(wParam);
+ MenuActions::toggleWindowOption(id - 42000);
+ }
+ else if ((uMsg == WM_COMMAND || uMsg == WM_SYSCOMMAND) && LOWORD(wParam) == WINAMP_MAIN_WINDOW)
+ {
+ for (int i = 0;i < SkinParser::getNumContainers();i++)
+ {
+ Container *cont = SkinParser::enumContainer(i);
+ if (!_wcsicmp(cont->getId(), L"main"))
+ {
+ cont->toggle();
+ return 1;
+ }
+ }
+ }
+ else if ((uMsg == WM_COMMAND || uMsg == WM_SYSCOMMAND) && LOWORD(wParam) == WINAMP_OPTIONS_EQ)
+ {
+ if (!gothrueqmsg)
+ return 0;
+ }
+ else if ((uMsg == WM_COMMAND || uMsg == WM_SYSCOMMAND))
+ {
+ switch (LOWORD(wParam))
+ {
+ case ID_CONTROLMENU_OPACITY_10: controlOpacity(10); return 0;
+ case ID_CONTROLMENU_OPACITY_20: controlOpacity(20); return 0;
+ case ID_CONTROLMENU_OPACITY_30: controlOpacity(30); return 0;
+ case ID_CONTROLMENU_OPACITY_40: controlOpacity(40); return 0;
+ case ID_CONTROLMENU_OPACITY_50: controlOpacity(50); return 0;
+ case ID_CONTROLMENU_OPACITY_60: controlOpacity(60); return 0;
+ case ID_CONTROLMENU_OPACITY_70: controlOpacity(70); return 0;
+ case ID_CONTROLMENU_OPACITY_80: controlOpacity(80); return 0;
+ case ID_CONTROLMENU_OPACITY_90: controlOpacity(90); return 0;
+ case ID_CONTROLMENU_OPACITY_100: controlOpacity(100); return 0;
+ case ID_CONTROLMENU_SCALING_50: controlScaling(0.5); return 0;
+ case ID_CONTROLMENU_SCALING_75: controlScaling(0.75); return 0;
+ case ID_CONTROLMENU_SCALING_100: controlScaling(1.0); return 0;
+ case ID_CONTROLMENU_SCALING_125: controlScaling(1.25); return 0;
+ case ID_CONTROLMENU_SCALING_150: controlScaling(1.5); return 0;
+ case ID_CONTROLMENU_SCALING_200: controlScaling(2.0); return 0;
+ case ID_CONTROLMENU_SCALING_250: controlScaling(2.5); return 0;
+ case ID_CONTROLMENU_SCALING_300: controlScaling(3.0); return 0;
+ case ID_CONTROLMENU_SCALING_LOCKED: lockScaling(1); return 0;
+ case ID_CONTROLMENU_SCALING_FOLLOWDOUBLESIZE: lockScaling(0); return 0;
+ case ID_CONTROLMENU_SCALING_CUSTOM: customScaling(); return 0;
+ case ID_CONTROLMENU_OPACITY_CUSTOM: customOpacity(); return 0;
+ case ID_CONTROLMENU_OPACITY_AUTO100_HOVER: autoOpacifyHover(); return 0;
+ case ID_CONTROLMENU_OPACITY_AUTO100_FOCUS: autoOpacifyFocus(); return 0;
+ case SC_MOVE:
+ {
+ Layout *l = SkinParser::getMainLayout();
+ if (l != NULL)
+ {
+ Container *c = l->getParentContainer();
+ if (c)
+ {
+ Layout *ll = c->getCurrentLayout();
+ if (ll) l = ll;
+ if (l)
+ {
+ if (!l->isVisible()) l->setVisible(1);
+ return SendMessageW(l->gethWnd(), WM_SYSCOMMAND, wParam, lParam);
+ }
+ }
+ }
+ break;
+ }
+ case ID_CONTROLMENU_TOOLBAR_DISABLED: controlAppBar(APPBAR_NOTDOCKED); break;
+ case ID_CONTROLMENU_TOOLBAR_TOP: controlAppBar(APPBAR_TOP); break;
+ case ID_CONTROLMENU_TOOLBAR_LEFT: controlAppBar(APPBAR_LEFT); break;
+ case ID_CONTROLMENU_TOOLBAR_RIGHT: controlAppBar(APPBAR_RIGHT); break;
+ case ID_CONTROLMENU_TOOLBAR_BOTTOM: controlAppBar(APPBAR_BOTTOM); break;
+ case ID_CONTROLMENU_TOOLBAR_ALWAYSONTOP: controlAppBarAOT(); break;
+ case ID_CONTROLMENU_TOOLBAR_AUTOHIDE: controlAppBarAH(); break;
+ case ID_CONTROLMENU_TOOLBAR_AUTODOCKONDRAG: cfg_options_appbarondrag = !cfg_options_appbarondrag; break;
+ }
+ }
+ }
+
+ return CallWinampWndProc(hwndDlg, uMsg, wParam, lParam);
+}
+
+void onLayoutChanged()
+{
+ if (DEFERREDCALLBACKMSG > 65536)
+ PostMessage(wa2.getMainWindow(), WM_WA_IPC, 1, DEFERREDCALLBACKMSG);
+}
+
+#ifdef DEBUG_CAPTURES
+int tid = 0;
+
+VOID TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD time)
+{
+ DebugString("Capture belongs to %x (foregroundwnd = %x)\n", GetCapture(), GetForegroundWindow());
+}
+#endif
+
+template <class api_T>
+static void ServiceBuild(api_T *&api_t, GUID factoryGUID_t)
+{
+ if (WASABI_API_SVC)
+ {
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(factoryGUID_t);
+ if (factory)
+ api_t = reinterpret_cast<api_T *>( factory->getInterface() );
+ }
+}
+
+template <class api_T>
+static void ServiceRelease(api_T *api_t, GUID factoryGUID_t)
+{
+ if (WASABI_API_SVC && api_t)
+ {
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(factoryGUID_t);
+ if (factory)
+ factory->releaseInterface(api_t);
+ }
+ api_t = NULL;
+}
+
+//-----------------------------------------------------------------------------------------------
+// initializes freeform library
+//-----------------------------------------------------------------------------------------------
+int m_loaded_at_all = 0;
+StringW g_resourcepath;
+
+void initFFApi()
+{
+ if ( !m_loaded_at_all )
+ {
+ m_loaded_at_all = 1;
+ api_service *svc = (api_service *)SendMessageW( wa2.getMainWindow(), WM_WA_IPC, 0, IPC_GET_API_SERVICE );
+
+ ServiceBuild( AGAVE_API_PLAYLISTS, api_playlistsGUID );
+ ServiceBuild( AGAVE_API_ALBUMART, albumArtGUID );
+ ServiceBuild( AGAVE_API_PLAYLISTMANAGER, api_playlistmanagerGUID );
+ ServiceBuild( WAC_API_DOWNLOADMANAGER, DownloadManagerGUID );
+ ServiceBuild( WASABI_API_COLORTHEMES, ColorThemesAPIGUID );
+ ServiceBuild( WASABI_API_PALETTE, PaletteManagerGUID );
+ ServiceBuild( WASABI_API_THREADPOOL, ThreadPoolGUID );
+
+ ApiInit::init( hInstance, wa2.getMainWindow(), svc );
+ cfgitems = new Wa2CfgItems();
+
+#ifdef DEBUG_CAPTURES
+ tid = SetTimer( NULL, 0x159, 50, (TIMERPROC)TimerProc );
+#endif
+
+ wchar_t filename[ WA_MAX_PATH ] = { 0 };
+ GetModuleFileNameW( hInstance, filename, WA_MAX_PATH );
+ PathParserW pp( filename );
+ StringW path;
+ for ( int i = 0; i < pp.getNumStrings() - 1; i++ )
+ {
+ path.AppendPath( pp.enumString( i ) );
+ }
+ path.AppendPath( L"freeform" );
+ path.AppendFolder( L"wacs" );
+
+ // we can load a somewhat restricted version of the wac format
+
+ ComponentManager::loadAll( path );
+ ComponentManager::postLoad();
+
+ ApiInit::widgets->loadResources();
+
+ startFSMonitor();
+ }
+ cfg_options_alwaysontop.setValueAsInt( wa2.isOnTop() );
+}
+
+//-----------------------------------------------------------------------------------------------
+// shutdown ff lib
+//-----------------------------------------------------------------------------------------------
+void shutdownFFApi()
+{
+ if (m_loaded_at_all)
+ {
+ ServiceRelease( AGAVE_API_PLAYLISTS, api_playlistsGUID);
+ ServiceRelease( AGAVE_API_ALBUMART, albumArtGUID);
+ ServiceRelease( AGAVE_API_PLAYLISTMANAGER, api_playlistmanagerGUID);
+ ServiceRelease( WAC_API_DOWNLOADMANAGER, DownloadManagerGUID);
+ ServiceRelease( WASABI_API_COLORTHEMES, ColorThemesAPIGUID);
+ ServiceRelease( WASABI_API_PALETTE, PaletteManagerGUID);
+ ServiceRelease( WASABI_API_THREADPOOL, ThreadPoolGUID);
+
+ stopFSMonitor();
+
+ // shutdown the library
+#ifdef DEBUG_CAPTURES
+ KillTimer(NULL, tid);
+#endif
+
+ delete cfgitems; cfgitems = NULL;
+ ApiInit::shutdown();
+ComponentManager::unloadAll();
+
+ m_loaded_at_all = 0;
+ }
+}
+
+static void MakeControlMenu()
+{
+ if (controlmenu)
+ return ;
+
+ controlmenu = WASABI_API_LOADMENU(IDR_CONTROLMENU);
+
+ if (!Wasabi::Std::Wnd::isDesktopAlphaAvailable())
+ EnableMenuItem(controlmenu, 0, MF_BYPOSITION | MF_GRAYED);
+}
+
+//-----------------------------------------------------------------------------------------------
+// go freeform
+//-----------------------------------------------------------------------------------------------
+void init_inst()
+{
+ if ( m_are_we_loaded )
+ return;
+
+ // set the classic main window to be transparent
+ // so we can move it around the screen to allow
+ // certain Windows 8 modes as well as improving
+ // where it is placed for some multi-mon setups
+ Wasabi::Std::Wnd::setLayeredWnd( wa2.getMainWindow(), 1 );
+ Wasabi::Std::Wnd::setLayeredAlpha( wa2.getMainWindow(), 0 );
+
+ initEgg();
+
+ wa2.setDrawBorders( 0 );
+ wa2.disableSkinnedCursors( 1 );
+
+ int wasminimized = IsIconic( wa2.getMainWindow() );
+ if ( wasminimized )
+ ShowWindow( wa2.getMainWindow(), SW_RESTORE );
+
+ MakeControlMenu();
+
+ going_freeform = 1;
+
+ Wa2WndEmbed::rememberVisibleWindows();
+
+ if ( wa2.isWindowVisible( IPC_GETWND_PE ) )
+ {
+ if ( !m_loading_at_startup ) WritePrivateProfileStringW( L"gen_ff", L"classicpe", L"1", INI_FILE );
+ }
+ else
+ if ( !m_loading_at_startup ) WritePrivateProfileStringW( L"gen_ff", L"classicpe", L"0", INI_FILE );
+
+ if ( wa2.isWindowVisible( IPC_GETWND_EQ ) )
+ {
+ gothrueqmsg = 1;
+ SendMessageW( plugin.hwndParent, WM_COMMAND, WINAMP_OPTIONS_EQ, 0 );
+ gothrueqmsg = 0;
+ if ( !m_loading_at_startup ) WritePrivateProfileStringW( L"gen_ff", L"classiceq", L"1", INI_FILE );
+ }
+ else
+ if ( !m_loading_at_startup ) WritePrivateProfileStringW( L"gen_ff", L"classiceq", L"0", INI_FILE );
+
+ removeEq();
+
+ if ( SendMessageW( plugin.hwndParent, WM_WA_IPC, 0, IPC_ISMAINWNDVISIBLE ) )
+ {
+ SendMessageW( plugin.hwndParent, WM_COMMAND, WINAMP_MAIN_WINDOW, 0 );
+ if ( !m_loading_at_startup ) WritePrivateProfileStringW( L"gen_ff", L"classicmw", L"1", INI_FILE );
+ }
+ else
+ if ( !m_loading_at_startup ) WritePrivateProfileStringW( L"gen_ff", L"classicmw", L"0", INI_FILE );
+
+ m_are_we_loaded = 1;
+
+ initFFApi();
+
+ // redirect drag and drop to winamp2 by default
+ WASABI_API_WND->setDefaultDropTarget( (void *)wa2.getDropTarget() );
+
+ // this installs a bunch of predefined groups to map wa3 to wa2 functionnality
+ groups = new Wa2Groupdefs();
+
+ // now load a skin ! the path to the skin is extracted and temporarilly becomes the official skins directory
+
+ StringW skinname = m_lastskin_nam;
+
+ removeSkinExtension( skinname );
+
+ before_startup_callback = 1;
+ WASABI_API_SKIN->skin_switchSkin( skinname, m_lastskin_dir );
+
+ /* // if we wanted to have drag&drop support for just the main window, we'd do it this way :-)
+ Container *maincontainer = SkinParser::getContainer("main");
+ if (maincontainer != NULL) {
+ for (int i=0;i<maincontainer->getNumLayouts();i++) {
+ Layout *layout = maincontainer->enumLayout(i);
+ if (layout != NULL) {
+ layout->setDropTarget((void *)wa2.getDropTarget());
+ }
+ }
+ }*/
+
+ // send event for dialog parent
+ onLayoutChanged();
+
+ if ( wa2.export_sa_setreq )
+ wa2.export_sa_setreq( 1 );
+
+ shuffle.setValueAsInt( wa2.getShuffle() );
+
+ int rep = wa2.getRepeat();
+ int manadv = wa2.getManualPlaylistAdvance();
+
+ disable_set_wa2_repeat = 1;
+ repeat.setValueAsInt( ( rep && manadv ) ? -1 : rep );
+ disable_set_wa2_repeat = 0;
+
+ if ( DEFERREDCALLBACKMSG > 65536 )
+ PostMessage( wa2.getMainWindow(), WM_WA_IPC, 2, DEFERREDCALLBACKMSG );
+
+ // so if some embedwindows are already visible, they update their look
+ PostMessage( wa2.getMainWindow(), WM_WA_IPC, 0xf00d, IPC_FF_ONCOLORTHEMECHANGED );
+
+ // monitor color theme
+ colorThemeMonitor = new ColorThemeMonitor();
+
+ syncDoubleSize( 1 );
+ syncDisplayMode();
+
+ going_freeform = 0;
+
+ if ( wa2.getWnd( IPC_GETWND_VIDEO ) )
+ {
+ oldVideoWnd = wa2.getWnd( IPC_GETWND_VIDEO );
+ if ( !oldVideoWndProc )
+ oldVideoWndProc = (WNDPROC)SetWindowLongPtrW( oldVideoWnd, GWLP_WNDPROC, (LONG_PTR)newVideoWndProc );
+ }
+
+ if ( wasminimized )
+ ShowWindow( wa2.getMainWindow(), SW_MINIMIZE );
+
+ if ( eggstat )
+ SetTimer( wa2.getMainWindow(), UPDATE_EGG, 25, NULL );
+}
+
+void quit_inst()
+{
+ if (!m_are_we_loaded) return ;
+
+ KillTimer(wa2.getMainWindow(), UPDATE_EGG);
+
+ wa2.setDrawBorders(1);
+ wa2.disableSkinnedCursors(0);
+
+ KillTimer(wa2.getMainWindow(), 0xC0DE);
+ KillTimer(wa2.getMainWindow(), 0xC0DE + 1);
+
+ EnableMenuItem(wa2.getMenuBarMenu(Winamp2FrontEnd::WA2_MAINMENUBAR_OPTIONS), WINAMP_OPTIONS_DSIZE, MF_ENABLED);
+ EnableMenuItem(GetSubMenu(wa2.getPopupMenu(), 11 + wa2.adjustOptionsPopupMenu(0)), WINAMP_OPTIONS_DSIZE, MF_ENABLED);
+
+ if (oldVideoWnd && oldVideoWndProc)
+ SetWindowLongPtrW(oldVideoWnd, GWLP_WNDPROC, (LONG_PTR)oldVideoWndProc);
+ oldVideoWndProc = 0;
+ oldVideoWnd = 0;
+
+ removeWindowOptionsFromContextMenu();
+
+ delete mainLayoutMonitor;
+ mainLayoutMonitor=0;
+
+ wa2.setDialogBoxParent(NULL);
+ unpopulateWindowsMenus();
+ restoreEq();
+
+ // unload the skin -- skinspath is restored to default
+ WASABI_API_SKIN->skin_unloadSkin();
+
+ // delete predefined groups service
+ delete groups; groups = NULL;
+
+ // delete options
+ delete ffoptions; ffoptions = NULL;
+
+ // stop monitoring color theme
+ delete colorThemeMonitor; colorThemeMonitor = NULL;
+
+ if (wa2.export_sa_setreq) wa2.export_sa_setreq(0);
+
+ m_are_we_loaded = 0;
+
+ int classicmw = GetPrivateProfileIntW(L"gen_ff", L"classicmw", 1, INI_FILE);
+ if (classicmw && !SendMessageW(plugin.hwndParent, WM_WA_IPC, 0, IPC_ISMAINWNDVISIBLE))
+ SendMessageW(plugin.hwndParent, WM_COMMAND, WINAMP_MAIN_WINDOW, 0);
+
+ CheckMenuItem(wa2.getPopupMenu(), WINAMP_MAIN_WINDOW, classicmw ? MF_CHECKED : MF_UNCHECKED);
+
+ if (GetPrivateProfileIntW(L"gen_ff", L"classiceq", 1, INI_FILE) && !wa2.isWindowVisible(IPC_GETWND_EQ))
+ {
+ gothrueqmsg = 1;
+ SendMessageW(plugin.hwndParent, WM_COMMAND, WINAMP_OPTIONS_EQ, 0);
+ gothrueqmsg = 0;
+ }
+
+ if (GetPrivateProfileIntW(L"gen_ff", L"classicpe", 1, INI_FILE) && !wa2.isWindowVisible(IPC_GETWND_PE))
+ {
+ SendMessageW(plugin.hwndParent, WM_COMMAND, WINAMP_OPTIONS_PLEDIT, 0);
+ }
+
+ // restore the classic main window to be solid
+ Wasabi::Std::Wnd::setLayeredWnd(wa2.getMainWindow(), 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+// init (from Winamp2)
+//-----------------------------------------------------------------------------------------------
+int init()
+{
+ // loader so that we can get the localisation service api for use
+ WASABI_API_SVC = (api_service*) SendMessageW(plugin.hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+ if (WASABI_API_SVC == (api_service*)1) WASABI_API_SVC = NULL;
+ if (!WASABI_API_SVC || WASABI_API_SVC == (api_service *)1)
+ return GEN_INIT_FAILURE;
+
+ static wchar_t modskin[128];
+ INI_FILE = (wchar_t*) SendMessageW(plugin.hwndParent, WM_WA_IPC, 0, IPC_GETINIFILEW);
+ INI_DIR = (wchar_t*) SendMessageW(plugin.hwndParent, WM_WA_IPC, 0, IPC_GETINIDIRECTORYW);
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
+ if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
+
+ // need to have this initialised before we try to do anything with localisation features
+ WASABI_API_START_LANG(plugin.hDllInstance,GenFFLangGUID);
+
+ swprintf(szDescription, ARRAYSIZE(szDescription),
+ WASABI_API_LNGSTRINGW(IDS_NULLSOFT_MODERN_SKINS), VERSION);
+ plugin.description = (char*)szDescription;
+
+ wa2.init(plugin.hwndParent);
+
+ DEFERREDCALLBACKMSG = SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)"gen_ff_deferred", IPC_REGISTER_WINAMP_IPCMESSAGE);
+ UPDATEDIALOGBOXPARENTMSG = SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)"gen_ff_update", IPC_REGISTER_WINAMP_IPCMESSAGE);
+
+ // subclass the Winamp2 main window to receive our callbacks
+ wa_oldWndProc = (WNDPROC) SetWindowLongPtrW(wa2.getMainWindow(), GWLP_WNDPROC, (LONG_PTR)wa_newWndProc);
+
+ ffPrefsItem.dlgID = IDD_PREFS;
+ ffPrefsItem.name = WASABI_API_LNGSTRINGW_BUF(IDS_MODERN_SKINS,modskin,128);
+ ffPrefsItem.proc = (void*)ffPrefsProc;
+ ffPrefsItem.hInst = WASABI_API_LNG_HINST;
+ ffPrefsItem.where = 2; //skins subtreeitem
+ SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&ffPrefsItem, IPC_ADD_PREFS_DLGW);
+
+ checkMlPresent();
+
+ m_loading_at_startup = 1;
+ onSkinSwitch();
+ m_loading_at_startup = 0;
+ return 0;
+}
+
+void RestoreClassicWinamp(int was_loaded)
+{
+ // JF> my proposed fix to the problems :)
+ // investigating doing this from winamp.exe on startup, gotta figure it out
+ if (INI_FILE && was_loaded) // restore winamp.ini to about what it shoulda been
+ {
+ int classicpews = GetPrivateProfileIntW(L"gen_ff", L"classicplws", 0, INI_FILE);
+ int classicwidth = GetPrivateProfileIntW(L"gen_ff", L"classicplwidth", 275, INI_FILE);
+ int classicheight = GetPrivateProfileIntW(L"gen_ff", L"classicplheight", 145, INI_FILE);
+ int classicmw = GetPrivateProfileIntW(L"gen_ff", L"classicmw", 1, INI_FILE);
+ int classiceq = GetPrivateProfileIntW(L"gen_ff", L"classiceq", 1, INI_FILE);
+ wchar_t buf[64] = {0};
+
+ wsprintfW(buf, L"%d", classicheight);
+ if (classicpews)
+ {
+ WritePrivateProfileStringW(L"winamp", L"pe_height", L"14", INI_FILE);
+ WritePrivateProfileStringW(L"winamp", L"pe_height_ws", buf, INI_FILE);
+ }
+ else
+ {
+ WritePrivateProfileStringW(L"winamp", L"pe_height", buf, INI_FILE);
+ WritePrivateProfileStringW(L"winamp", L"pe_height_ws", L"", INI_FILE);
+ }
+ wsprintfW(buf, L"%d", classicwidth);
+ WritePrivateProfileStringW(L"winamp", L"pe_width", buf, INI_FILE);
+
+ WritePrivateProfileStringW(L"winamp", L"eq_open", classiceq ? L"1" : L"0", INI_FILE);
+ WritePrivateProfileStringW(L"winamp", L"mw_open", classicmw ? L"1" : L"0", INI_FILE);
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+// quit (from Winamp 2)
+//-----------------------------------------------------------------------------------------------
+void quit()
+{
+ int was_loaded = m_are_we_loaded;
+ quit_inst();
+
+ RestoreClassicWinamp(was_loaded);
+ // restore wa2's windowproc
+ //SetWindowLong(wa2.getMainWindow(), GWL_WNDPROC, (LONG)wa_oldWndProc);
+ shutdownFFApi();
+}
+
+//-----------------------------------------------------------------------------------------------
+// About box wndproc
+//-----------------------------------------------------------------------------------------------
+ifc_window *about_group = NULL;
+StringW oldrenderer;
+BOOL CALLBACK aboutProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ oldrenderer = cfg_options_fontrenderer.getValue();
+ if (!WCSCASEEQLSAFE(cfg_options_fontrenderer.getValue(), L"FreeType"))
+ cfg_options_fontrenderer.setValue(L"FreeType");
+ about_group = WASABI_API_SKIN->group_create(L"wasabi.gen_ff.about");
+ about_group->setVirtual(0);
+ HWND w = GetDlgItem(hwndDlg, IDC_STATIC_GROUP);
+ about_group->setStartHidden(1);
+ about_group->init(WASABI_API_WND->main_getRootWnd(), 1);
+ SetWindowLong(about_group->gethWnd(), GWL_STYLE, GetWindowLong(about_group->gethWnd(), GWL_STYLE) | WS_CHILD);
+ SetParent(about_group->gethWnd(), w);
+ SetWindowLong(w, GWL_STYLE, GetWindowLong(w, GWL_STYLE) | WS_CLIPCHILDREN);
+ RECT r;
+ GetClientRect(w, &r);
+ about_group->resize(r.left + 1, r.top + 1, r.right - r.left - 2, r.bottom - r.top - 2);
+ about_group->setVisible(1);
+ C_Group g(about_group->getGuiObject()->guiobject_getScriptObject());
+ ScriptObject *ver = g.findObject(L"version");
+ if (ver)
+ {
+ C_Text t(ver);
+ t.setText(StringPrintfW(L". © 2003-2023 Winamp SA %s", VERSION));
+ }
+ ShowWindow(about_group->gethWnd(), SW_NORMAL);
+ return 1;
+ }
+ case WM_DESTROY:
+ WASABI_API_SKIN->group_destroy(about_group);
+ about_group = NULL;
+ break;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDOK: case IDCANCEL:
+ if (!WCSCASEEQLSAFE(cfg_options_fontrenderer.getValue(), oldrenderer))
+ cfg_options_fontrenderer.setValue(oldrenderer);
+ EndDialog(hwndDlg, 0);
+ return 0;
+ }
+ return 0;
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------------------------
+// configure plugin (from Winamp 2)
+//-----------------------------------------------------------------------------------------------
+void config()
+{
+ if (m_loaded_at_all)
+ {
+ StringW skin = WASABI_API_SKIN->getSkinName();
+ wchar_t _skName[64] = {0};
+ WASABI_API_LNGSTRINGW_BUF(IDS_NO_SKIN_LOADED_,_skName,64);
+
+ if ((!skin.iscaseequal(_skName)) || guiTree->getNumObject() > 0)
+ {
+ WASABI_API_DIALOGBOXW(IDD_ABOUT, wa2.getPreferencesWindow(), aboutProc);
+ return ;
+ }
+ }
+
+ MSGBOXPARAMSW msgbx = {sizeof(MSGBOXPARAMS),0};
+ msgbx.lpszText = WASABI_API_LNGSTRINGW(IDS_MODERN_SKIN_SUPPORT_CLASSIC);
+ msgbx.lpszCaption = szDescription;
+ msgbx.lpszIcon = MAKEINTRESOURCEW(102);
+ msgbx.hInstance = GetModuleHandle(0);
+ msgbx.dwStyle = MB_USERICON;
+ MessageBoxIndirectW(&msgbx);
+}
+
+//-----------------------------------------------------------------------------------------------
+// expose the genpurp plugin interface to dll
+//-----------------------------------------------------------------------------------------------
+extern "C" __declspec(dllexport) winampGeneralPurposePlugin * winampGetGeneralPurposePlugin() { return &plugin; }
+
+//-----------------------------------------------------------------------------------------------
+// a window was right clicked where there was no custom context menu available, spawn Wa2's menu
+//-----------------------------------------------------------------------------------------------
+void appContextMenu(ifc_window *w)
+{
+ if (!WASABI_API_WND->rootwndIsValid(w)) return ;
+ WASABI_API_WND->appdeactivation_setbypass(1);
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ w->setFocus();
+ DWORD p = GetMessagePos();
+ int x = GET_X_LPARAM(p);
+ int y = GET_Y_LPARAM(p);
+ addWindowOptionsToContextMenu(w);
+ wa2.triggerPopupMenu(x, y);
+ WASABI_API_WND->appdeactivation_setbypass(0);
+}
+
+//-----------------------------------------------------------------------------------------------
+void updateControlMenu(ifc_window *w)
+{
+ int curalpha = 255;
+ double curratio = 1.;
+ int opacitysafe = 0;
+ int scalelocked = 0;
+ int auto100_hover = 0;
+ int auto100_focus = 0;
+
+ if (g_controlMenuTarget == NULL) return ;
+
+ if (w)
+ {
+ ifc_window *rootparent = g_controlMenuTarget->getDesktopParent();
+ if (rootparent && rootparent->getInterface(layoutGuid))
+ {
+ Layout *l = static_cast<Layout*>(rootparent);
+ opacitysafe = l->isTransparencySafe();
+ scalelocked = l->isScaleLocked();
+ curratio = w->getRenderRatio();
+ if (!cfg_uioptions_linkallalpha.getValueAsInt())
+ {
+ auto100_hover = l->getAutoOpacify() == 1;
+ auto100_focus = l->getAutoOpacify() == 2;
+ curalpha = l->getAlpha();
+ }
+ else
+ {
+ auto100_hover = l->getAlphaMgr()->getAutoOpacify() == 1;
+ auto100_focus = l->getAlphaMgr()->getAutoOpacify() == 2;
+ curalpha = l->getAlphaMgr()->getGlobalAlpha();
+ }
+ }
+ }
+
+ HMENU ctrlmenu = GetSubMenu(controlmenu, 0);
+ EnableMenuItem(ctrlmenu, 0, MF_BYPOSITION | (opacitysafe ? MF_ENABLED : MF_GRAYED));
+ HMENU scalemenu = GetSubMenu(ctrlmenu, 1);
+ HMENU alphamenu = GetSubMenu(ctrlmenu, 0);
+ int uselocks = cfg_uioptions_uselocks.getValueAsInt();
+ CheckMenuItem(scalemenu, ID_CONTROLMENU_SCALING_LOCKED, MF_BYCOMMAND | ((scalelocked || !uselocks) ? MF_CHECKED : MF_UNCHECKED));
+ EnableMenuItem(scalemenu, ID_CONTROLMENU_SCALING_LOCKED, MF_BYCOMMAND | (uselocks ? MF_ENABLED : MF_GRAYED));
+ CheckMenuItem(scalemenu, ID_CONTROLMENU_SCALING_FOLLOWDOUBLESIZE, MF_BYCOMMAND | (scalelocked || !uselocks ? MF_UNCHECKED : MF_CHECKED));
+ EnableMenuItem(scalemenu, ID_CONTROLMENU_SCALING_FOLLOWDOUBLESIZE, MF_BYCOMMAND | (uselocks ? MF_ENABLED : MF_GRAYED));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_AUTO100_HOVER, MF_BYCOMMAND | (auto100_hover ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_AUTO100_FOCUS, MF_BYCOMMAND | (auto100_focus ? MF_CHECKED : MF_UNCHECKED));
+
+ int v = (int)((curalpha / 255.0f * 100.0f) + 0.5f);
+ int u = (int)((curratio * 100.0f) + 0.5f);
+
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_10, MF_BYCOMMAND | (v == 10 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_20, MF_BYCOMMAND | (v == 20 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_30, MF_BYCOMMAND | (v == 30 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_40, MF_BYCOMMAND | (v == 40 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_50, MF_BYCOMMAND | (v == 50 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_60, MF_BYCOMMAND | (v == 60 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_70, MF_BYCOMMAND | (v == 70 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_80, MF_BYCOMMAND | (v == 80 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_90, MF_BYCOMMAND | (v == 90 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_100, MF_BYCOMMAND | (v == 100 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(scalemenu, ID_CONTROLMENU_SCALING_50, MF_BYCOMMAND | (u == 50 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(scalemenu, ID_CONTROLMENU_SCALING_75, MF_BYCOMMAND | (u == 75 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(scalemenu, ID_CONTROLMENU_SCALING_100, MF_BYCOMMAND | (u == 100 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(scalemenu, ID_CONTROLMENU_SCALING_125, MF_BYCOMMAND | (u == 125 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(scalemenu, ID_CONTROLMENU_SCALING_150, MF_BYCOMMAND | (u == 150 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(scalemenu, ID_CONTROLMENU_SCALING_200, MF_BYCOMMAND | (u == 200 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(scalemenu, ID_CONTROLMENU_SCALING_250, MF_BYCOMMAND | (u == 250 ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(scalemenu, ID_CONTROLMENU_SCALING_300, MF_BYCOMMAND | (u == 300 ? MF_CHECKED : MF_UNCHECKED));
+
+ if (u != 50 && u != 75 && u != 100 && u != 125 && u != 150 && u != 200 && u != 250 && u != 300)
+ {
+ ModifyMenuW(scalemenu, ID_CONTROLMENU_SCALING_CUSTOM, MF_BYCOMMAND | MF_STRING, ID_CONTROLMENU_SCALING_CUSTOM, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_CUSTOM_X_PERCENT), u));
+ CheckMenuItem(scalemenu, ID_CONTROLMENU_SCALING_CUSTOM, MF_BYCOMMAND | MF_CHECKED);
+ }
+ else
+ {
+ ModifyMenuW(scalemenu, ID_CONTROLMENU_SCALING_CUSTOM, MF_BYCOMMAND | MF_STRING, ID_CONTROLMENU_SCALING_CUSTOM, WASABI_API_LNGSTRINGW(IDS_CUSTOM));
+ CheckMenuItem(scalemenu, ID_CONTROLMENU_SCALING_CUSTOM, MF_BYCOMMAND | MF_UNCHECKED);
+ }
+ if (((float)v / 10.0) - (v / 10) != 0.0)
+ {
+ ModifyMenuW(alphamenu, ID_CONTROLMENU_OPACITY_CUSTOM, MF_BYCOMMAND | MF_STRING, ID_CONTROLMENU_OPACITY_CUSTOM, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_CUSTOM_X_PERCENT), v));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_CUSTOM, MF_BYCOMMAND | MF_CHECKED);
+ }
+ else
+ {
+ ModifyMenuW(alphamenu, ID_CONTROLMENU_OPACITY_CUSTOM, MF_BYCOMMAND | MF_STRING, ID_CONTROLMENU_OPACITY_CUSTOM, WASABI_API_LNGSTRINGW(IDS_CUSTOM));
+ CheckMenuItem(alphamenu, ID_CONTROLMENU_OPACITY_CUSTOM, MF_BYCOMMAND | MF_UNCHECKED);
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+// a window has triggered the control menu (control scale & alpha)
+//-----------------------------------------------------------------------------------------------
+void appControlMenu(ifc_window *w)
+{
+ WASABI_API_WND->appdeactivation_setbypass(1);
+ int x, y;
+ if (w)
+ {
+ Wasabi::Std::getMousePos(&x, &y);
+ g_controlMenuTarget = w;
+ updateControlMenu(w);
+ updateAppBarMenu(w);
+ HMENU ctrlmenu = GetSubMenu(controlmenu, 0);
+ DoTrackPopup(ctrlmenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON, x, y, wa2.getMainWindow());
+ }
+ WASABI_API_WND->appdeactivation_setbypass(0);
+}
+
+//-----------------------------------------------------------------------------------------------
+// a close application button was clicked
+//-----------------------------------------------------------------------------------------------
+void appQuit()
+{
+ if (!wa2.isExitEnabled()) return ;
+ wa2.quit(); // this is in fact *posting* a quit message
+}
+
+
+//-----------------------------------------------------------------------------------------------
+// a fatal skin error occured, we should revert to the wa2 skin (deferred)
+//-----------------------------------------------------------------------------------------------
+#define DCB_UNLOADSKIN 64
+
+class deferredUnloadSkin : public TimerClientDI
+{
+public:
+ deferredUnloadSkin()
+ {
+ timerclient_postDeferredCallback(DCB_UNLOADSKIN, 0);
+ }
+
+ virtual int timerclient_onDeferredCallback(intptr_t param1, intptr_t param2)
+ {
+ if (param1 == DCB_UNLOADSKIN)
+ {
+ quit_inst();
+ delete this;
+ return 1;
+ }
+ else return TimerClientDI::timerclient_onDeferredCallback(param1, param2);
+ }
+};
+
+//-----------------------------------------------------------------------------------------------
+// this is the actual event for skin fata errors, it is called when a try/except block failed
+// upon calling a skin operation which should not be able to fail (ie: calling a script function pointer)
+//-----------------------------------------------------------------------------------------------
+void onFatalSkinError()
+{
+ new deferredUnloadSkin();
+}
+
+
+//-----------------------------------------------------------------------------------------------
+// map a GUID to the toggling of a window for which there is no permanent wndCreationService,
+// ie: library, prefs, avs
+//-----------------------------------------------------------------------------------------------
+
+// called by a skinwnd_toggle call when the guid isn't found in the wndcreation services
+int onCreateExternalWindowGuid(GUID g)
+{
+ if (g == library_guid)
+ {
+ SendMessageW(wa2.getMainWindow(), WM_COMMAND, ID_FILE_SHOWLIBRARY, 0);
+ return 1;
+ }
+ else if (g == preferences_guid)
+ {
+ SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_OPTIONS_PREFS, 0);
+ return 1;
+ }
+ else if (g == about_guid)
+ {
+ SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_HELP_ABOUT, 0);
+ return 1;
+ }
+ else if (g == lightning_bolt_guid)
+ {
+ SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_LIGHTNING_CLICK, 0);
+ return 1;
+ }
+ else if (g == colorthemes_guid)
+ {
+ last_page.setData(L"3");
+ SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&ffPrefsItem, IPC_OPENPREFSTOPAGE);
+ return 1;
+ }
+ else if (g == avs_guid)
+ {
+ if (wa2.isVisRunning())
+ {
+ SetTimer(wa2.getMainWindow(), 0xC0DE, 50, NULL);
+ SetTimer(wa2.getMainWindow(), 0xC0DE + 1, 5000, NULL);
+ }
+ else
+ wa2.toggleVis();
+ return 1;
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------------------------
+void onToggleDesktopAlpha(int v)
+{
+ if (!toggle_from_wa2 && subWndId == 0 && IsWindow(subWnd)) SendMessageW(subWnd, WM_INITDIALOG, 0, 0);
+}
+
+
+//-----------------------------------------------------------------------------------------------
+// changes the name of a container so that static containers with the wrong name don't load the config
+// values off the wrong name. this should match the WindowText of the embededwindow. note: this is only
+// necessary for static containers holding an internal embedwnd (ie: library, avs, but not third party wnds
+// as they can't be refered to by GUID anyway [if they can't be refered to by GUID, you can't make a static
+// container for them])
+//-----------------------------------------------------------------------------------------------
+
+const wchar_t *onTweakContainerNameW(const wchar_t *name)
+{
+ static wchar_t tweaked[96];
+ ZERO(tweaked);
+ if (!_wcsicmp(name, WASABI_API_LNG->GetStringFromGUIDW(GenMlLangGUID, plugin.hDllInstance, 18, tweaked, sizeof(tweaked)/sizeof(wchar_t))) ||
+ !_wcsicmp(name, L"Media Library") ||
+ !_wcsicmp(name, L"Winamp Library") ||
+ !_wcsicmp(name, L"Library"))
+ {
+ return WASABI_API_LNGSTRINGW_BUF(IDS_MEDIA_LIBRARY,tweaked, sizeof(tweaked)/sizeof(wchar_t));
+ }
+ if (!_wcsicmp(name, L"Avs")) return WASABI_API_LNGSTRINGW_BUF(IDS_VISUALIZATIONS,tweaked, sizeof(tweaked)/sizeof(wchar_t));
+ return name;
+}
+
+const wchar_t *GetMenuItemString(HMENU menu, int id, int bypos)
+{
+ static StringW rtn;
+ rtn.trunc(0);
+ MENUITEMINFOW info = {sizeof(info), MIIM_DATA | MIIM_TYPE | MIIM_STATE | MIIM_ID, MFT_STRING, };
+ GetMenuItemInfoW(menu, id, bypos, &info);
+ if (info.cch > 0)
+ {
+ info.dwTypeData = WMALLOC(++info.cch + 1);
+ GetMenuItemInfoW(menu, id, bypos, &info);
+ info.dwTypeData[info.cch] = 0;
+ rtn = info.dwTypeData;
+ FREE(info.dwTypeData);
+ }
+ return rtn;
+}
+
+StringW eqmenustring;
+
+//-----------------------------------------------------------------------------------------------
+void removeEq()
+{
+ if (eqremoved) return ;
+ eqremoved = 1;
+ eqmenustring = GetMenuItemString(wa2.getPopupMenu(), WINAMP_OPTIONS_EQ, FALSE);
+ RemoveMenu(wa2.getPopupMenu(), WINAMP_OPTIONS_EQ, MF_BYCOMMAND);
+ wa2.adjustOptionsPopupMenu(-1);
+}
+
+//-----------------------------------------------------------------------------------------------
+void restoreEq()
+{
+ if (!eqremoved) return ;
+ MENUITEMINFOW i = {sizeof(i), MIIM_ID | MIIM_STATE | MIIM_TYPE, MFT_STRING, wa2.isWindowVisible(IPC_GETWND_EQ) ? MFS_CHECKED : 0, WINAMP_OPTIONS_EQ};
+ i.dwTypeData = eqmenustring.getNonConstVal();
+ InsertMenuItemW(wa2.getPopupMenu(), 8, TRUE, &i);
+ wa2.adjustOptionsPopupMenu(1);
+ eqremoved = 0;
+}
+
+//-----------------------------------------------------------------------------------------------
+void unpopulateWindowsMenus()
+{
+ if (ffwindowsitempos == -1) return ;
+
+ HMENU menuBarMenu = wa2.getMenuBarMenu(Winamp2FrontEnd::WA2_MAINMENUBAR_WINDOWS);
+ for(int i = GetMenuItemCount(menuBarMenu)-1; i >= 0; i--)
+ {
+ MENUITEMINFOW info = {sizeof(info), MIIM_DATA, 0, };
+ if(GetMenuItemInfoW(menuBarMenu,i,TRUE,&info))
+ {
+ if(info.dwItemData == 0xD01){
+ RemoveMenu(menuBarMenu,i,MF_BYPOSITION);
+ wa2.adjustFFWindowsMenu(-1);
+ }
+ }
+ }
+
+ HMENU menuPopupMenu = wa2.getPopupMenu();
+ for(int i = GetMenuItemCount(menuPopupMenu)-1; i >= 0; i--)
+ {
+ MENUITEMINFOW info = {sizeof(info), MIIM_DATA, 0, };
+ if(GetMenuItemInfoW(menuPopupMenu,i,TRUE,&info))
+ {
+ if(info.dwItemData == 0xD01){
+ RemoveMenu(menuPopupMenu,i,MF_BYPOSITION);
+ wa2.adjustOptionsPopupMenu(-1);
+ }
+ }
+ }
+
+ ffwindowsitempos = -1;
+ ffwindowsitempos2 = -1;
+
+ MenuActions::removeSkinWindowOptions();
+ MenuActions::removeSkinOptions();
+}
+
+//-----------------------------------------------------------------------------------------------
+void populateWindowsMenus()
+{
+ if (ffwindowsitempos != -1) unpopulateWindowsMenus();
+ MenuActions::installSkinOptions();
+ MenuActions::installSkinWindowOptions();
+
+ ffwindowsitempos = wa2.adjustFFWindowsMenu(0) + NUMSTATICWINDOWS;
+ ffwindowsitempos2 = wa2.adjustOptionsPopupMenu(0) + 6 + NUMSTATICWINDOWS + 1;
+
+ MENUITEMINFOW i = {sizeof(i), };
+ i.fMask = MIIM_TYPE | MIIM_DATA | MIIM_ID | MIIM_STATE;
+ i.fType = MFT_STRING;
+ i.wID = 43000;
+ i.dwItemData = 0xD01; // use this as a check so we're only removing the correct items!!
+ int pos = ffwindowsitempos;
+ int pos2 = ffwindowsitempos2;
+ PtrListQuickSorted<StringW, StringWComparator> items;
+
+ HMENU hMenu = wa2.getMenuBarMenu(Winamp2FrontEnd::WA2_MAINMENUBAR_WINDOWS);
+ HMENU hMenu2 = wa2.getPopupMenu();
+ for (int c = 0;c < SkinParser::getNumContainers();c++)
+ {
+ Container *cont = SkinParser::enumContainer(c);
+ if (cont && wantContainerInMenu(cont))
+ {
+ i.dwTypeData = const_cast<wchar_t *>(cont->getName());
+ if (i.dwTypeData != NULL)
+ {
+ if (!items.findItem(i.dwTypeData))
+ {
+ items.addItem(new StringW(i.dwTypeData));
+ i.cch = wcslen(i.dwTypeData);
+ i.fState = cont->isVisible() ? MFS_CHECKED : 0;
+ InsertMenuItemW(hMenu, pos++, TRUE, &i);
+ wa2.adjustFFWindowsMenu(1);
+ InsertMenuItemW(hMenu2, pos2++, TRUE, &i);
+ wa2.adjustOptionsPopupMenu(1);
+ }
+ }
+ }
+ i.wID++;
+ }
+
+ int n = WASABI_API_WNDMGR->autopopup_getNumGuids();
+ for (int c = 0;c < n;c++)
+ {
+ GUID guid = WASABI_API_WNDMGR->autopopup_enumGuid(c);
+ const wchar_t *groupdesc = WASABI_API_WNDMGR->autopopup_enumGuidDescription(c);
+ if (guid != INVALID_GUID && groupdesc && *groupdesc)
+ {
+ i.dwTypeData = const_cast<wchar_t *>(groupdesc);
+ if (!items.findItem(i.dwTypeData))
+ {
+ items.addItem(new StringW(i.dwTypeData));
+ i.cch = wcslen(i.dwTypeData);
+ i.fState = WASABI_API_WNDMGR->skinwnd_getNumByGuid(guid) ? MFS_CHECKED : 0;
+ InsertMenuItemW(hMenu, pos++, TRUE, &i);
+ wa2.adjustFFWindowsMenu(1);
+ InsertMenuItemW(hMenu2, pos2++, TRUE, &i);
+ wa2.adjustOptionsPopupMenu(1);
+ }
+ }
+ i.wID++;
+ }
+
+ n = WASABI_API_WNDMGR->autopopup_getNumGroups();
+ for (int c = 0;c < n;c++)
+ {
+ const wchar_t *id = WASABI_API_WNDMGR->autopopup_enumGroup(c);
+ const wchar_t *groupdesc = WASABI_API_WNDMGR->autopopup_enumGroupDescription(c);
+ if (id && groupdesc && *id && *groupdesc)
+ {
+ i.dwTypeData = const_cast<wchar_t *>(groupdesc);
+ // allow localisation of the color editor menu item
+ i.dwTypeData = const_cast<wchar_t *>(MenuActions::localizeSkinWindowName(i.dwTypeData));
+ if (!items.findItem(i.dwTypeData))
+ {
+ items.addItem(new StringW(i.dwTypeData));
+ i.cch = wcslen(i.dwTypeData);
+ i.fState = WASABI_API_WNDMGR->skinwnd_getNumByGroupId(id) ? MFS_CHECKED : 0;
+ InsertMenuItemW(hMenu, pos++, TRUE, &i);
+ wa2.adjustFFWindowsMenu(1);
+ InsertMenuItemW(hMenu2, pos2++, TRUE, &i);
+ wa2.adjustOptionsPopupMenu(1);
+ }
+ }
+ i.wID++;
+ }
+
+ items.deleteAll();
+ ffwindowstop = i.wID;
+}
+
+//-----------------------------------------------------------------------------------------------
+void switchSkin(const wchar_t *skinname)
+{
+ wa2.switchSkin(skinname);
+}
+
+//-----------------------------------------------------------------------------------------------
+void addWindowOptionsToContextMenu(ifc_window *w)
+{
+ if (g_controlMenuTarget != NULL)
+ removeWindowOptionsFromContextMenu();
+ if (w == NULL && WASABI_API_WND->rootwndIsValid(lastFocused))
+ w = lastFocused;
+ g_controlMenuTarget = w;
+
+ if (g_controlMenuTarget == NULL) return ;
+
+ /*int opacitysafe = 1;
+ int scalelocked = 0;
+
+ ifc_window *rootparent = g_controlMenuTarget->getDesktopParent();
+ if (rootparent && rootparent->getInterface(layoutGuid))
+ {
+ Layout *l = static_cast<Layout*>(rootparent);
+ opacitysafe = l->isTransparencySafe();
+ scalelocked = l->isScaleLocked();
+ }*/
+
+ updateControlMenu(w);
+ updateAppBarMenu(w);
+
+ HMENU menu = wa2.getPopupMenu();
+ HMENU ctrlmenu = GetSubMenu(controlmenu, 0);
+
+ // JF> Francis, made this use command IDs (inserts it right before the help ID in the main menu).
+ // does this look OK? if you want, revert back to the old one. I just thought this seemed a tiny
+ // bit cleaner... :)
+#define ID_HELP_HELPTOPICS 40347
+ InsertMenuW(menu, ID_HELP_HELPTOPICS, MF_BYCOMMAND | MF_POPUP, (UINT_PTR)ctrlmenu, WASABI_API_LNGSTRINGW(IDS_WINDOW_SETTINGS));
+ InsertMenu(menu, ID_HELP_HELPTOPICS, MF_BYCOMMAND | MF_SEPARATOR, 0, NULL);
+
+}
+
+//-----------------------------------------------------------------------------------------------
+void removeWindowOptionsFromContextMenu()
+{
+ if (g_controlMenuTarget == NULL) return ;
+ g_controlMenuTarget = NULL;
+ HMENU menu = wa2.getPopupMenu();
+ HMENU ctrlmenu = GetSubMenu(controlmenu, 0);
+ if (ctrlmenu)
+ {
+ int l = GetMenuItemCount(menu);
+ while (l-- > 0 && GetSubMenu(menu, l) != ctrlmenu);
+ if (l >= 0)
+ {
+ RemoveMenu(menu, l, MF_BYPOSITION);
+ RemoveMenu(menu, l, MF_BYPOSITION); // remove sep
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+void controlOpacity(int v)
+{
+ if (!g_controlMenuTarget) return ;
+ if (!WASABI_API_WND->rootwndIsValid(g_controlMenuTarget)) return ;
+ v = (int)(((float)v / 100.0f) * 255.0f + 0.5f);
+ ifc_window *rootparent = g_controlMenuTarget->getDesktopParent();
+ if (rootparent && rootparent->getInterface(layoutGuid))
+ {
+ Layout *l = static_cast<Layout*>(rootparent);
+ if (!cfg_uioptions_linkallalpha.getValueAsInt())
+ {
+ l->setAlpha(v);
+ }
+ else
+ {
+ cfg_uioptions_linkedalpha.setValueAsInt(v);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+void controlScaling(double v)
+{
+ if (!g_controlMenuTarget) return ;
+ if (!WASABI_API_WND->rootwndIsValid(g_controlMenuTarget)) return ;
+ ifc_window *rootparent = g_controlMenuTarget->getDesktopParent();
+ if (rootparent) rootparent->setRenderRatio(v);
+}
+
+//-----------------------------------------------------------------------------------------------
+void lockScaling(int lock)
+{
+ ifc_window *rootparent = g_controlMenuTarget->getDesktopParent();
+ if (!WASABI_API_WND->rootwndIsValid(g_controlMenuTarget)) return ;
+ if (rootparent && rootparent->getInterface(layoutGuid))
+ {
+ Layout *l = static_cast<Layout*>(rootparent);
+ l->lockScale(lock);
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+void controlAppBar(int side)
+{
+ ifc_window *rootparent = g_controlMenuTarget->getDesktopParent();
+ if (rootparent)
+ {
+ AppBar *ab = (AppBar *)rootparent->getInterface(appBarGuid);
+ if (ab)
+ {
+ ab->appbar_dock(side);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+void controlAppBarAOT()
+{
+ ifc_window *rootparent = g_controlMenuTarget->getDesktopParent();
+ if (rootparent)
+ {
+ Layout *l = (Layout *)rootparent->getInterface(layoutGuid);
+ if (l)
+ {
+ int curaot = l->getAppBarAlwaysOnTop();
+ l->setAppBarAlwaysOnTop(!curaot);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+void controlAppBarAH()
+{
+ ifc_window *rootparent = g_controlMenuTarget->getDesktopParent();
+ if (rootparent)
+ {
+ Layout *l = (Layout *)rootparent->getInterface(layoutGuid);
+ if (l)
+ {
+ int curah = l->getAppBarAutoHide();
+ l->setAppBarAutoHide(!curah);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+void updateAppBarMenu(ifc_window *w)
+{
+ if (g_controlMenuTarget == NULL) return ;
+ ifc_window *rootparent = g_controlMenuTarget->getDesktopParent();
+ if (rootparent)
+ {
+ Layout *l = (Layout *)rootparent->getInterface(layoutGuid);
+ if (l)
+ {
+ HMENU ctrlmenu = GetSubMenu(controlmenu, 0);
+ HMENU appbarmenu = GetSubMenu(ctrlmenu, 2);
+ if (l->appbar_getEnabledSides() == 0)
+ {
+ EnableMenuItem(ctrlmenu, 2, MF_BYPOSITION | MF_GRAYED);
+ return ;
+ }
+ else
+ EnableMenuItem(ctrlmenu, 2, MF_BYPOSITION | MF_ENABLED);
+ int docked = l->appbar_isDocked();
+ int side = l->appbar_getSide();
+ CheckMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_ALWAYSONTOP, MF_BYCOMMAND | (l->appbar_wantAlwaysOnTop() ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_AUTOHIDE, MF_BYCOMMAND | (l->appbar_wantAutoHide() ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_LEFT, MF_BYCOMMAND | ((docked && side == APPBAR_LEFT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_TOP, MF_BYCOMMAND | ((docked && side == APPBAR_TOP) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_RIGHT, MF_BYCOMMAND | ((docked && side == APPBAR_RIGHT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_BOTTOM, MF_BYCOMMAND | ((docked && side == APPBAR_BOTTOM) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_DISABLED, MF_BYCOMMAND | (!docked ? MF_CHECKED : MF_UNCHECKED));
+ EnableMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_AUTOHIDE, MF_BYCOMMAND | ((!docked || l->appbar_isSideAutoHideSafe(side)) ? MF_ENABLED : MF_GRAYED));
+ EnableMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_LEFT, MF_BYCOMMAND | (l->appbar_isSideEnabled(APPBAR_LEFT) ? MF_ENABLED : MF_GRAYED));
+ EnableMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_TOP, MF_BYCOMMAND | (l->appbar_isSideEnabled(APPBAR_TOP) ? MF_ENABLED : MF_GRAYED));
+ EnableMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_RIGHT, MF_BYCOMMAND | (l->appbar_isSideEnabled(APPBAR_RIGHT) ? MF_ENABLED : MF_GRAYED));
+ EnableMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_BOTTOM, MF_BYCOMMAND | (l->appbar_isSideEnabled(APPBAR_BOTTOM) ? MF_ENABLED : MF_GRAYED));
+ CheckMenuItem(appbarmenu, ID_CONTROLMENU_TOOLBAR_AUTODOCKONDRAG, MF_BYCOMMAND | (cfg_options_appbarondrag ? MF_CHECKED : MF_UNCHECKED));
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+double onTweakRenderRatio(double v)
+{
+ if (!cfg_uioptions_uselocks.getValueAsInt())
+ return v;
+ return wa2.isDoubleSize() ? 2.0 : 1.0;
+}
+
+//-----------------------------------------------------------------------------------------------
+void onCustomAltF4()
+{
+ SendMessageW(wa2.getMainWindow(), WM_CLOSE, 0, 0);
+}
+
+int isSkinStillLoading()
+{
+ return before_startup_callback;
+}
+
+//-----------------------------------------------------------------------------------------------
+void loadExtraColorThemes()
+{
+ wchar_t filename[WA_MAX_PATH] = {0};
+ GetModuleFileNameW(hInstance, filename, WA_MAX_PATH);
+ PathParserW pp(filename);
+ StringW path;
+ for (int i = 0;i < pp.getNumStrings() - 1;i++)
+ {
+ path.AppendPath(pp.enumString(i));
+ }
+ StringW file = path;
+ file.AppendPath(L"ColorThemes");
+ file.AppendPath(WASABI_API_SKIN->getSkinName());
+ file.AppendPath(L"*.xml");
+ WASABI_API_SKIN->loadSkinFile(file);
+}
+
+double oldscale = 1.;
+
+//-----------------------------------------------------------------------------------------------
+static BOOL CALLBACK customScaleProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ //CUT: double curratio=1.;
+ ifc_window *rootparent = g_controlMenuTarget->getDesktopParent();
+ if (!rootparent || !WASABI_API_WND->rootwndIsValid(rootparent))
+ {
+ g_controlMenuTarget = NULL; return TRUE;
+ }
+
+ oldscale = rootparent->getRenderRatio();
+
+ int u = (int)((oldscale * 100.0f) + 0.5f);
+
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_CUSTOMSCALE), TBM_SETRANGEMAX, 0, 300);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_CUSTOMSCALE), TBM_SETRANGEMIN, 0, 10);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_CUSTOMSCALE), TBM_SETPOS, 1, u);
+ SetDlgItemTextW(hwndDlg, IDC_STATIC_SCALE, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_SCALE_X_PERCENT), u));
+ return TRUE;
+ }
+ case WM_HSCROLL:
+ {
+ int t = (int)SendMessageW((HWND) lParam, TBM_GETPOS, 0, 0);
+ if ((HWND) lParam == GetDlgItem(hwndDlg, IDC_SLIDER_CUSTOMSCALE))
+ {
+ SetDlgItemTextW(hwndDlg, IDC_STATIC_SCALE, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_SCALE_X_PERCENT), t));
+ controlScaling((double)t / 100.0);
+ if (g_controlMenuTarget)
+ {
+ ifc_window *w = g_controlMenuTarget->getDesktopParent();
+ UpdateWindow(w->gethWnd());
+ }
+ }
+ break;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ EndDialog(hwndDlg, IDOK);
+ return 0;
+ case IDCANCEL:
+ EndDialog(hwndDlg, IDCANCEL);
+ return 0;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+double oldalpha = 255.;
+
+//-----------------------------------------------------------------------------------------------
+static BOOL CALLBACK customAlphaProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ ifc_window *rootparent = g_controlMenuTarget->getDesktopParent();
+ if (!rootparent || !WASABI_API_WND->rootwndIsValid(rootparent))
+ {
+ g_controlMenuTarget = NULL; return TRUE;
+ }
+
+ int v = 100;
+ if (!cfg_uioptions_linkallalpha.getValueAsInt())
+ {
+ Layout *l = static_cast<Layout *>(rootparent);
+ if (l != NULL)
+ oldalpha = static_cast<double>(l->getAlpha());
+ }
+ else
+ {
+ oldalpha = static_cast<double>(cfg_uioptions_linkedalpha.getValueAsInt());
+ }
+ v = (int)((oldalpha / 255.0f * 100.0f) + 0.5f);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_CUSTOMALPHA), TBM_SETRANGEMAX, 0, 100);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_CUSTOMALPHA), TBM_SETRANGEMIN, 0, 10);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_CUSTOMALPHA), TBM_SETPOS, 1, v);
+ SetDlgItemTextW(hwndDlg, IDC_STATIC_ALPHA, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_OPACITY_X_PERCENT), v));
+ return TRUE;
+ }
+ case WM_HSCROLL:
+ {
+ int t = (int)SendMessageW((HWND) lParam, TBM_GETPOS, 0, 0);
+ if ((HWND) lParam == GetDlgItem(hwndDlg, IDC_SLIDER_CUSTOMALPHA))
+ {
+ SetDlgItemTextW(hwndDlg, IDC_STATIC_ALPHA, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_OPACITY_X_PERCENT), t));
+ controlOpacity(t);
+ }
+ break;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ EndDialog(hwndDlg, IDOK);
+ return 0;
+ case IDCANCEL:
+ EndDialog(hwndDlg, IDCANCEL);
+ return 0;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+void customScaling()
+{
+ if (!g_controlMenuTarget) return ;
+ if (!WASABI_API_WND->rootwndIsValid(g_controlMenuTarget)) return ;
+ ifc_window *w = g_controlMenuTarget->getDesktopParent();
+ if (!w || !WASABI_API_WND->rootwndIsValid(w)) return ;
+ int r = WASABI_API_DIALOGBOXW(IDD_CUSTOMSCALE, w->gethWnd(), customScaleProc);
+ if (r != IDOK)
+ controlScaling(oldscale);
+}
+
+void customOpacity()
+{
+ if (!g_controlMenuTarget) return ;
+ if (!WASABI_API_WND->rootwndIsValid(g_controlMenuTarget)) return ;
+ ifc_window *w = g_controlMenuTarget->getDesktopParent();
+ if (!w || !WASABI_API_WND->rootwndIsValid(w)) return ;
+ int r = WASABI_API_DIALOGBOXW(IDD_CUSTOMALPHA, w->gethWnd(), customAlphaProc);
+ if (r != IDOK)
+ controlOpacity((int)((oldalpha / 255.0f * 100.0f) + 0.5f));
+}
+
+void autoOpacifyHover()
+{
+ if (!g_controlMenuTarget) return ;
+ if (!WASABI_API_WND->rootwndIsValid(g_controlMenuTarget)) return ;
+ ifc_window *w = g_controlMenuTarget->getDesktopParent();
+ Layout *l = static_cast<Layout*>(w->getInterface(layoutGuid));
+ if (l)
+ {
+ if (!cfg_uioptions_linkallalpha.getValueAsInt())
+ {
+ int a = l->getAutoOpacify();
+ if (a == 2) a = 1;
+ else a = !a;
+ l->setAutoOpacify(a);
+ }
+ else
+ {
+ int a = cfg_uioptions_autoopacitylinked.getValueAsInt();
+ if (a == 2) a = 1;
+ else a = !a;
+ cfg_uioptions_autoopacitylinked.setValueAsInt(a);
+ }
+ }
+}
+
+void autoOpacifyFocus()
+{
+ if (!g_controlMenuTarget) return ;
+ if (!WASABI_API_WND->rootwndIsValid(g_controlMenuTarget)) return ;
+ ifc_window *w = g_controlMenuTarget->getDesktopParent();
+ Layout *l = static_cast<Layout*>(w->getInterface(layoutGuid));
+ if (l)
+ {
+ if (!cfg_uioptions_linkallalpha.getValueAsInt())
+ {
+ int a = l->getAutoOpacify();
+ if (a == 1) a = 2;
+ else if (a == 0) a = 2;
+ else if (a == 2) a = 0;
+ l->setAutoOpacify(a);
+ }
+ else
+ {
+ int a = cfg_uioptions_autoopacitylinked.getValueAsInt();
+ if (a == 1) a = 2;
+ else if (a == 0) a = 2;
+ else if (a == 2) a = 0;
+ cfg_uioptions_autoopacitylinked.setValueAsInt(a);
+ }
+ }
+}
+
+StringW langpackfilename;
+
+const wchar_t *localesCustomGetFile()
+{
+ const wchar_t *langDir = WASABI_API_LNG->GetLanguageFolder();
+ if (!langDir || !*langDir)
+ return NULL;
+
+ langpackfilename = StringPathCombine(langDir, L"freeform");
+ return langpackfilename;
+#if 0 // old code
+ wchar_t buf[256] = L"";
+ GetPrivateProfileStringW(L"Winamp", L"langpack", L"", buf, 256, AutoWide(INI_FILE)); // TODO: maybe we should change all ini file stuff to W versions
+ if (*buf == 0)
+ return NULL;
+ wchar_t *p = wcschr(buf, '.');
+ if (p)
+ *p = 0;
+
+ wchar_t filename[WA_MAX_PATH] = {0};
+ GetModuleFileNameW(hInstance, filename, WA_MAX_PATH);
+ PathParserW pp(filename);
+ langpackfilename = L"";
+
+ for (int i = 0;i < pp.getNumStrings() - 1;i++)
+ {
+ langpackfilename.AppendPath(pp.enumString(i));
+ }
+ langpackfilename.AppendPath(L"freeform");
+ langpackfilename.AppendPath(L"langpacks");
+ langpackfilename.AppendPath(StringPrintfW(L"%s.xml", buf));
+
+ return langpackfilename;
+#endif
+}
+
+const wchar_t *getCustomVar(const wchar_t *var)
+{
+ static StringW ret;
+ if (WCSCASEEQLSAFE(var, L"@HAVE_LIBRARY@"))
+ {
+ ret = StringPrintfW(L"%d", we_have_ml);
+ return ret;
+ }
+ return NULL;
+}
+
+void checkMlPresent()
+{
+ wchar_t filename[WA_MAX_PATH] = {0};
+ GetModuleFileNameW(hInstance, filename, WA_MAX_PATH);
+ PathParserW pp(filename);
+ StringW path;
+ for (int i = 0;i < pp.getNumStrings() - 1;i++)
+ {
+ path.AppendPath(pp.enumString(i));
+ }
+ path.AppendPath(L"gen_ml.dll");
+ we_have_ml = !WACCESS(path, 0);
+}
+
+void initEgg()
+{
+ eggstr[0] = ~'N';
+ eggstr[1] = ~'U';
+ eggstr[2] = ~'L';
+ eggstr[3] = ~'L';
+ eggstr[4] = ~'S';
+ eggstr[5] = ~'O';
+ eggstr[6] = ~'F';
+ eggstr[7] = ~'T';
+ eggstr[8] = 0;
+
+ {
+ int x;
+ for (x = 0; x < 8; x ++) eggstr[x] ^= 255;
+ }
+}
+
+void toggleEgg()
+{
+ eggstat = !eggstat;
+ if (!eggstat)
+ {
+ KillTimer(wa2.getMainWindow(), UPDATE_EGG);
+ if (lastlayoutegg && WASABI_API_WND->rootwndIsValid(lastlayoutegg)) lastlayoutegg->setTransparencyOverride(-1);
+ lastlayoutegg = NULL;
+ }
+ else SetTimer(wa2.getMainWindow(), UPDATE_EGG, 25, NULL);
+}
+
+void getCustomMetaData(const wchar_t *field, wchar_t *buf, int len)
+{
+ StringW curfile = WASABI_API_MEDIACORE->core_getCurrent(0);
+ if (curfile.isempty())
+ {
+ buf[0] = 0;
+ return ;
+ }
+ if (!_wcsnicmp(curfile, L"file://", 7))
+ curfile = StringW(curfile.getValue() + 7);
+ buf[0] = 0;
+
+ if (WCSCASEEQLSAFE(field, L"filename"))
+ {
+ WCSCPYN(buf, curfile, len);
+ }
+ else
+ {
+ wa2.getMetaData(curfile, field, buf, len);
+ }
+}
+
+void registerGlobalHotkeys()
+{
+ static int registered = 0;
+ if (!registered)
+ {
+ static wchar_t ghkStr[96];
+ wa2.registerGlobalHotkey((char*)WASABI_API_LNGSTRINGW_BUF(IDS_GHK_SHOW_NOTIFICATION,ghkStr,96), WM_WA_IPC, 0, IPC_SHOW_NOTIFICATION, HKF_UNICODE_NAME, "genff shn");
+ registered = 1;
+ }
+}
+
+const wchar_t *getSongInfoText()
+{
+ return Core::getSongInfoText();
+}
+
+const wchar_t *getSongInfoTextTranslated()
+{
+ return Core::getSongInfoTextTranslated();
+}
+
+OSWINDOWHANDLE getKeyboardForwardWnd(GUID g)
+{
+ if (g != INVALID_GUID)
+ {
+ if (g == playerWndGuid)
+ return wa2.getMainWindow();
+ else if (g == pleditWndGuid)
+ return wa2.getWnd(IPC_GETWND_PE);
+ else if (g == videoWndGuid)
+ return wa2.getWnd(IPC_GETWND_VIDEO);
+ else
+ {
+ embedWindowState *ews = embedWndGuidMgr.getEmbedWindowState(g);
+ if (ews && wa2.isValidEmbedWndState(ews)) return ews->me;
+ }
+ }
+ return WASABI_API_WND->main_getRootWnd()->gethWnd();
+}
+
+void onAppBarDockChanged(ifc_window *w)
+{
+ setDialogBoxesParent();
+}
+
+void onMainLayoutMove(HWND w)
+{
+ // for Winamp to appear on the correct taskbar on Windows 8
+ // its necessary to set the classic main window to appear on
+ // that monitor and to be on-screen (but hidden) otherwise
+ // Windows will ignore it and it then makes us look buggy.
+ RECT r;
+ Wasabi::Std::getViewport(&r, w, 1);
+ SetWindowPos(wa2.getMainWindow(), NULL, r.left, r.bottom - 1, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW);
+}
+
+void updateAll()
+{
+ updatePl();
+#ifdef MINIBROWSER_SUPPORT
+ updateMb();
+#endif
+ updateVid();
+ int n = embedWndGuidMgr.getNumWindowStates();
+ for (int i = 0;i < n;i++)
+ {
+ embedWindowState *ws = NULL;
+ GUID g = embedWndGuidMgr.enumWindowState(i, &ws);
+ if (g != INVALID_GUID)
+ {
+ updateEmb(g, ws);
+ }
+ }
+}
+
+void onReParent(HWND wnd)
+{
+ updateAll();
+}
+
+void onReInit(HWND wnd)
+{
+ updateAll();
+}
+
+void startFSMonitor()
+{
+ g_fsmonitor = new FullScreenMonitor();
+ g_fscallback = new Wa5FSCallback();
+ g_fsmonitor->registerCallback(g_fscallback);
+}
+
+void stopFSMonitor()
+{
+ delete g_fsmonitor;
+ g_fsmonitor = NULL;
+ delete g_fscallback;
+ g_fscallback = NULL;
+}
+
+void updateParentlessOnTop()
+{
+ int i;
+ for (i = 0;i < SkinParser::getNumContainers();i++)
+ {
+ Container *c = SkinParser::enumContainer(i);
+ if (c != NULL)
+ {
+ int j;
+ for (j = 0;j < c->getNumLayouts();j++)
+ {
+ Layout *l = c->enumLayout(j);
+ if (l != NULL)
+ {
+ // skip windows owned by winamp
+ // skip appbars, they take care of themselves
+ if (l->getNoParent() && !l->appbar_isDocked())
+ {
+ l->updateOnTop();
+ }
+ }
+ }
+ }
+ }
+}
+
+void onGoFullscreen()
+{
+ // hidden windows will not receive APPBAR_CALLBACK, so forward it to winamp's main
+ SendMessageW(wa2.getMainWindow(), APPBAR_CALLBACK, ABN_FULLSCREENAPP, 1);
+ // update ontop flag for windows that are not parented to winamp
+ updateParentlessOnTop();
+}
+
+void onCancelFullscreen()
+{
+ // hidden windows will not receive APPBAR_CALLBACK, so forward it to winamp's main
+ SendMessageW(wa2.getMainWindow(), APPBAR_CALLBACK, ABN_FULLSCREENAPP, 0);
+ // update ontop flag for windows that are not owned by winamp
+ updateParentlessOnTop();
+}
+
+int processGenericHotkey(const char *hk)
+{
+ if (!m_are_we_loaded) return 0;
+
+ SystemObject::onKeyDown(AutoWide(StringPrintf("HOTKEY: %s", hk)));
+ if (VCPU::getComplete())
+ {
+ DebugStringW(L"HOTKEY: %s trapped by script\n", hk);
+ return 1;
+ }
+ return 0;
+}
+
+int canExitWinamp()
+{
+ return wa2.isExitEnabled();
+}
+
+int fsMonitorIsFS()
+{
+ return g_fsmonitor->isFullScreen();
+}
+
+void modalPush()
+{
+ wa2.pushExitDisabled();
+}
+
+void modalPop()
+{
+ wa2.popExitDisabled();
+} \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/main.h b/Src/Plugins/General/gen_ff/main.h
new file mode 100644
index 00000000..d831919b
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/main.h
@@ -0,0 +1,29 @@
+#ifndef __GEN_FF_MAIN_H
+#define __GEN_FF_MAIN_H
+
+class ifc_window;
+
+extern ifc_window *plWnd;
+extern ifc_window *mbWnd;
+extern ifc_window *vidWnd;
+
+#define NUMSTATICWINDOWS 3
+
+#include "../playlist/api_playlists.h"
+extern api_playlists *playlistsApi;
+#define AGAVE_API_PLAYLISTS playlistsApi
+
+#include "../Agave/AlbumArt/api_albumart.h"
+extern api_albumart *albumArtApi;
+#define AGAVE_API_ALBUMART albumArtApi
+
+#include "../playlist/api_playlistmanager.h"
+extern api_playlistmanager *playlistManagerApi;
+#define AGAVE_API_PLAYLISTMANAGER playlistManagerApi
+
+#include "../Components/wac_downloadManager/wac_downloadManager_api.h"
+
+#include "../Winamp/gen.h"
+extern "C" winampGeneralPurposePlugin plugin;
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/menuactions.cpp b/Src/Plugins/General/gen_ff/menuactions.cpp
new file mode 100644
index 00000000..266dd74a
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/menuactions.cpp
@@ -0,0 +1,787 @@
+#include "precomp__gen_ff.h"
+#include "menuactions.h"
+#include "wa2frontend.h"
+#include <api/skin/skinparse.h>
+#include "wa2cfgitems.h"
+#include "main.h"
+#include "resource.h"
+#include <api/locales/xlatstr.h>
+#include "../gen_ml/ml_ipc.h"
+#include "../winamp/gen.h"
+#include "../Agave/Language/api_language.h"
+#include "../gen_ml/menufucker.h"
+#include "../Winamp/strutil.h"
+
+extern librarySendToMenuStruct mainSendTo;
+#define WINAMP_OPTIONS_DSIZE 40165
+extern void addWindowOptionsToContextMenu(ifc_window *w);
+extern void removeWindowOptionsFromContextMenu();
+extern ifc_window *g_controlMenuTarget;
+extern HMENU controlmenu;
+int lowest_itempos = 0;
+int highest_itempos = -1;
+int lowest_witempos = 0;
+int lowest_witempos2 = 0;
+int highest_witempos = -1;
+int highest_witempos2 = -1;
+int optionsmenu_wa = 1;
+TList<HMENU> menulist;
+TList<HMENU> wmenulist;
+int in_menu = 0;
+
+
+//-----------------------------------------------------------------------------------------------
+MenuActions::MenuActions()
+{
+ registerAction(L"menu", _ACTION_MENU);
+ registerAction(L"sysmenu", _ACTION_SYSMENU);
+ registerAction(L"controlmenu", _ACTION_CONTROLMENU);
+ registerAction(L"MENU:WA5:File", ACTION_WA5FILEMENU);
+ registerAction(L"MENU:WA5:Play", ACTION_WA5PLAYMENU);
+ registerAction(L"MENU:WA5:Options", ACTION_WA5OPTIONSMENU);
+ registerAction(L"MENU:WA5:Windows", ACTION_WA5WINDOWSMENU);
+ registerAction(L"MENU:WA5:Help", ACTION_WA5HELPMENU);
+ registerAction(L"MENU:WA5:PE_File", ACTION_WA5PEFILEMENU);
+ registerAction(L"MENU:WA5:PE_Playlist", ACTION_WA5PEPLAYLISTMENU);
+ registerAction(L"MENU:WA5:PE_Sort", ACTION_WA5PESORTMENU);
+ registerAction(L"MENU:WA5:PE_Help", ACTION_WA5PEHELPMENU);
+ registerAction(L"MENU:WA5:ML_File", ACTION_WA5MLFILEMENU);
+ registerAction(L"MENU:WA5:ML_View", ACTION_WA5MLVIEWMENU);
+ registerAction(L"MENU:WA5:ML_Help", ACTION_WA5MLHELPMENU);
+ registerAction(L"PE_Add", ACTION_PEADD);
+ registerAction(L"PE_Rem", ACTION_PEREM);
+ registerAction(L"PE_Sel", ACTION_PESEL);
+ registerAction(L"PE_Misc", ACTION_PEMISC);
+ registerAction(L"PE_List", ACTION_PELIST);
+ registerAction(L"PE_ListOfLists", ACTION_PELISTOFLISTS);
+ registerAction(L"VID_FS", ACTION_VIDFS);
+ registerAction(L"VID_1X", ACTION_VID1X);
+ registerAction(L"VID_2X", ACTION_VID2X);
+ registerAction(L"VID_TV", ACTION_VIDTV);
+ registerAction(L"VID_Misc", ACTION_VIDMISC);
+ registerAction(L"VIS_Next", ACTION_VISNEXT);
+ registerAction(L"VIS_Prev", ACTION_VISPREV);
+ registerAction(L"VIS_FS", ACTION_VISFS);
+ registerAction(L"VIS_CFG", ACTION_VISCFG);
+ registerAction(L"VIS_Menu", ACTION_VISMENU);
+ registerAction(L"trackinfo", ACTION_TRACKINFO);
+ registerAction(L"trackmenu", ACTION_TRACKMENU);
+ registerAction(L"ML_SendTo", ACTION_SENDTO);
+}
+
+//-----------------------------------------------------------------------------------------------
+MenuActions::~MenuActions()
+{}
+
+static LRESULT sendMlIpc(int msg, WPARAM param) {
+ static HWND mlwnd = NULL;
+ if(!IsWindow(mlwnd)) {
+ int IPC_GETMLWINDOW = (INT)SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&"LibraryGetWnd", IPC_REGISTER_WINAMP_IPCMESSAGE);
+ if(IPC_GETMLWINDOW > 65536) mlwnd = (HWND)SendMessageW(plugin.hwndParent,WM_WA_IPC,0,IPC_GETMLWINDOW);
+ }
+ if(!IsWindow(mlwnd)) return 0;
+ return SendMessageW(mlwnd,WM_ML_IPC,param,msg);
+}
+
+//-----------------------------------------------------------------------------------------------
+int MenuActions::onActionId(int pvtid, const wchar_t *action, const wchar_t *param /* =NULL */, int p1 /* =0 */, int p2 /* =0 */, void *data /* =NULL */, int datalen /* =0 */, ifc_window *source /* =NULL */)
+{
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ RECT r = {0, 0, 0, 0};
+ if (source) source->getWindowRect(&r);
+ int height = r.bottom - r.top;
+ int width = r.right - r.left;
+ in_menu = 1;
+ switch (pvtid)
+ {
+ case _ACTION_MENU:
+ {
+ if (!_wcsicmp(param, L"presets"))
+ {
+ wa2.triggerEQPresetMenu(p1, p2);
+ }
+ }
+ break;
+ case _ACTION_SYSMENU:
+ {
+ addWindowOptionsToContextMenu(source);
+ wa2.triggerPopupMenu(p1, p2);
+ break;
+ }
+ case _ACTION_CONTROLMENU:
+ {
+ if (g_controlMenuTarget != NULL)
+ removeWindowOptionsFromContextMenu();
+ addWindowOptionsToContextMenu(g_controlMenuTarget);
+ g_controlMenuTarget = source;
+
+ HMENU ctrlmenu = GetSubMenu(controlmenu, 0);
+ DoTrackPopup(ctrlmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, p1, p2, wa2.getMainWindow());
+ break;
+ }
+ case ACTION_WA5FILEMENU:
+ {
+ wa2.triggerFileMenu(p1, p2, width, height);
+ break;
+ }
+ case ACTION_WA5PLAYMENU:
+ {
+ wa2.triggerPlayMenu(p1, p2, width, height);
+ break;
+ }
+ case ACTION_WA5OPTIONSMENU:
+ {
+ wa2.triggerOptionsMenu(p1, p2, width, height);
+ break;
+ }
+ case ACTION_WA5WINDOWSMENU:
+ {
+ wa2.triggerWindowsMenu(p1, p2, width, height);
+ break;
+ }
+ case ACTION_WA5HELPMENU:
+ {
+ wa2.triggerHelpMenu(p1, p2, width, height);
+ break;
+ }
+ case ACTION_WA5PEFILEMENU:
+ {
+ wa2.triggerPEFileMenu(p1, p2, width, height);
+ break;
+ }
+ case ACTION_WA5PEPLAYLISTMENU:
+ {
+ wa2.triggerPEPlaylistMenu(p1, p2, width, height);
+ break;
+ }
+ case ACTION_WA5PESORTMENU:
+ {
+ wa2.triggerPESortMenu(p1, p2, width, height);
+ break;
+ }
+ case ACTION_WA5PEHELPMENU:
+ {
+ wa2.triggerPEHelpMenu(p1, p2, width, height);
+ break;
+ }
+ case ACTION_WA5MLFILEMENU:
+ {
+ wa2.triggerMLFileMenu(p1, p2, width, height);
+ break;
+ }
+ case ACTION_WA5MLVIEWMENU:
+ {
+ wa2.triggerMLViewMenu(p1, p2, width, height);
+ break;
+ }
+ case ACTION_WA5MLHELPMENU:
+ {
+ wa2.triggerMLHelpMenu(p1, p2, width, height);
+ break;
+ }
+ case ACTION_PEADD:
+ {
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_ADD, r.left, r.top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
+ break;
+ }
+ case ACTION_PEREM:
+ {
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_REM, r.left, r.top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
+ break;
+ }
+ case ACTION_PESEL:
+ {
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_SEL, r.left, r.top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
+ break;
+ }
+ case ACTION_PEMISC:
+ {
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_MISC, r.left, r.top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
+ break;
+ }
+ case ACTION_PELIST:
+ {
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_LIST, r.right, r.top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
+ break;
+ }
+ case ACTION_PELISTOFLISTS:
+ {
+ wa2.triggerPEListOfListsMenu(r.left, r.top);
+ break;
+ }
+ case ACTION_VIDFS:
+ {
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_FULLSCREEN);
+ break;
+ }
+ case ACTION_VID1X:
+ {
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_1X);
+ break;
+ }
+ case ACTION_VID2X:
+ {
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_2X);
+ break;
+ }
+ case ACTION_VIDTV:
+ {
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_LIB);
+ break;
+ }
+ case ACTION_VIDMISC:
+ {
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDPOPUP_MISC, r.right, r.top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
+ break;
+ }
+ case ACTION_VISNEXT:
+ {
+ wa2.visNext();
+ break;
+ }
+ case ACTION_VISPREV:
+ {
+ wa2.visPrev();
+ break;
+ }
+ case ACTION_VISFS:
+ {
+ wa2.visFullscreen();
+ break;
+ }
+ case ACTION_VISCFG:
+ {
+ wa2.visConfig();
+ break;
+ }
+ case ACTION_VISMENU:
+ {
+ wa2.visMenu();
+ break;
+ }
+ case ACTION_TRACKMENU:
+ {
+ extern const wchar_t *GetMenuItemString(HMENU menu, int id, int bypos);
+#define WINAMP_TOGGLE_AUTOSCROLL 40189
+#define ID_RATING5 40396
+#define ID_RATING4 40397
+#define ID_RATING3 40398
+#define ID_RATING2 40399
+#define ID_RATING1 40400
+#define ID_RATING0 40401
+ HMENU top_menu = wa2.getTopMenu();
+ HMENU contextmenus = GetSubMenu(top_menu, 3);
+ HMENU songinfomenu = GetSubMenu(contextmenus, 0);
+ HMENU ratingmenu = GetSubMenu(songinfomenu, 5);
+ int rating = wa2.getCurTrackRating();
+ CheckMenuItem(ratingmenu, ID_RATING5, (rating == 5) ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem(ratingmenu, ID_RATING4, (rating == 4) ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem(ratingmenu, ID_RATING3, (rating == 3) ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem(ratingmenu, ID_RATING2, (rating == 2) ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem(ratingmenu, ID_RATING1, (rating == 1) ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem(ratingmenu, ID_RATING0, (rating == 0) ? MF_CHECKED : MF_UNCHECKED);
+ StringW olditemstr = GetMenuItemString(songinfomenu, 3, TRUE);
+ RemoveMenu(songinfomenu, 3, MF_BYPOSITION);
+
+ LRESULT IPC_LIBRARY_SENDTOMENU = SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&"LibrarySendToMenu", IPC_REGISTER_WINAMP_IPCMESSAGE);
+ HMENU menu = 0;
+ memset(&mainSendTo, 0, sizeof(mainSendTo));
+ if (IPC_LIBRARY_SENDTOMENU > 65536 && SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)0, IPC_LIBRARY_SENDTOMENU) == 0xffffffff)
+ {
+ char stStr[32] = {0};
+ MENUITEMINFOA mii = {sizeof(mii), MIIM_SUBMENU | MIIM_TYPE, MFT_STRING, };
+ mii.hSubMenu = menu = CreatePopupMenu();
+ mii.dwTypeData = WASABI_API_LNGSTRING_BUF(IDS_SEND_TO,stStr,32);
+ mii.cch = strlen((char*)mii.dwTypeData);
+
+ InsertMenuItemA(songinfomenu, 3, TRUE, &mii);
+
+ mainSendTo.mode = 1;
+ mainSendTo.hwnd = plugin.hwndParent; // TODO???
+ mainSendTo.data_type = ML_TYPE_FILENAMESW;
+ mainSendTo.build_hMenu = menu;
+ }
+
+ menufucker_t mf = {sizeof(mf),MENU_SONGTICKER,songinfomenu,0x3000,0x4000,0};
+ pluginMessage message_build = {SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&"menufucker_build", IPC_REGISTER_WINAMP_IPCMESSAGE),(intptr_t)&mf,0};
+ sendMlIpc(ML_IPC_SEND_PLUGIN_MESSAGE,(WPARAM)&message_build);
+
+ int ret = DoTrackPopup(songinfomenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON|TPM_RETURNCMD, p1, p2, wa2.getMainWindow());
+
+ pluginMessage message_result = {SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&"menufucker_result", IPC_REGISTER_WINAMP_IPCMESSAGE),(intptr_t)&mf,ret,0};
+ sendMlIpc(ML_IPC_SEND_PLUGIN_MESSAGE,(WPARAM)&message_result);
+
+ if (menu)
+ {
+ if (mainSendTo.mode == 2)
+ {
+ mainSendTo.menu_id = ret;
+ if (SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&mainSendTo, IPC_LIBRARY_SENDTOMENU) == 0xffffffff)
+ {
+ wchar_t buf[FILENAME_SIZE + 1] = {0};
+ wchar_t *end=buf;
+ size_t endSize = 0;
+ const wchar_t *entry = wa2.getFileW(wa2.getCurPlaylistEntry());
+ if (entry && *entry)
+ {
+ StringCchCopyExW(buf, FILENAME_SIZE, entry, &end, &endSize, 0);
+
+ mainSendTo.mode = 3;
+ mainSendTo.data = buf;
+ mainSendTo.data_type = ML_TYPE_FILENAMESW;
+ SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&mainSendTo, IPC_LIBRARY_SENDTOMENU);
+ }
+ }
+ }
+ // remove sendto
+ DeleteMenu(songinfomenu, 3, MF_BYPOSITION);
+ }
+ if (mainSendTo.mode)
+ {
+ mainSendTo.mode = 4;
+ SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&mainSendTo, IPC_LIBRARY_SENDTOMENU); // cleanup
+ memset(&mainSendTo, 0, sizeof(mainSendTo));
+ }
+ InsertMenuW(songinfomenu, 3, MF_BYPOSITION | MF_STRING, WINAMP_TOGGLE_AUTOSCROLL, olditemstr);
+ if (ret) SendMessageW(wa2.getMainWindow(), WM_COMMAND, ret, 0); // TODO?
+
+ break;
+ }
+ case ACTION_SENDTO:
+ {
+ LRESULT IPC_LIBRARY_SENDTOMENU = SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&"LibrarySendToMenu", IPC_REGISTER_WINAMP_IPCMESSAGE);
+ HMENU menu = 0;
+ memset(&mainSendTo, 0, sizeof(mainSendTo));
+ if (IPC_LIBRARY_SENDTOMENU > 65536 && SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)0, IPC_LIBRARY_SENDTOMENU) == 0xffffffff)
+ {
+ menu = CreatePopupMenu();
+
+ mainSendTo.mode = 1;
+ mainSendTo.hwnd = plugin.hwndParent; // TODO???
+ mainSendTo.data_type = ML_TYPE_FILENAMESW;
+ mainSendTo.build_hMenu = menu;
+ }
+ int ret = DoTrackPopup(menu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON|TPM_RETURNCMD, p1, p2, wa2.getMainWindow());
+ if (menu)
+ {
+ if (mainSendTo.mode == 2)
+ {
+ mainSendTo.menu_id = ret;
+ if (SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&mainSendTo, IPC_LIBRARY_SENDTOMENU) == 0xffffffff)
+ {
+ wchar_t buf[FILENAME_SIZE + 1] = {0};
+ wchar_t *end=buf;
+ size_t endSize = 0;
+ const wchar_t *entry = wa2.getFileW(wa2.getCurPlaylistEntry());
+ if (entry && *entry)
+ {
+ StringCchCopyExW(buf, FILENAME_SIZE, entry, &end, &endSize, 0);
+
+ mainSendTo.mode = 3;
+ mainSendTo.data = buf;
+ mainSendTo.data_type = ML_TYPE_FILENAMESW;
+ SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&mainSendTo, IPC_LIBRARY_SENDTOMENU);
+ }
+ }
+ }
+ }
+ if (mainSendTo.mode)
+ {
+ mainSendTo.mode = 4;
+ SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&mainSendTo, IPC_LIBRARY_SENDTOMENU); // cleanup
+ memset(&mainSendTo, 0, sizeof(mainSendTo));
+ }
+
+ }
+ break;
+ case ACTION_TRACKINFO:
+ {
+ wa2.openTrackInfo();
+ break;
+ }
+ }
+ in_menu = 0;
+ return 1;
+}
+
+HMENU MenuActions::makeSkinOptionsSubMenu(GUID g, int *cmdoffset)
+{
+ CfgItem *item = WASABI_API_CONFIG->config_getCfgItemByGuid(g);
+ if (item != NULL)
+ {
+ HMENU menu = CreatePopupMenu();
+ int n = MIN(item->getNumAttributes(), 500);
+ for (int i = 0;i < n;i++)
+ {
+ const wchar_t *attr = item->enumAttribute(i);
+ if (attr && *attr)
+ {
+ HMENU submenu = NULL;
+ wchar_t txt[256] = {0};
+ item->getData(attr, txt, 256);
+ GUID g = nsGUID::fromCharW(txt);
+ if (g != INVALID_GUID)
+ { // submenu !
+ submenu = makeSkinOptionsSubMenu(g, cmdoffset);
+ }
+ int v = item->getDataAsInt(attr, 0);
+ if (WCSCASEEQLSAFE(txt, L"-"))
+ {
+ InsertMenu(menu, i, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
+ }
+ else
+ InsertMenuW(menu, i, ((v && !submenu) ? MF_CHECKED : MF_UNCHECKED) | MF_STRING | MF_BYPOSITION | (submenu ? MF_POPUP : 0), submenu ? (UINT_PTR)submenu : 44000 + *cmdoffset, _(attr));
+ }
+ (*cmdoffset)++;
+ }
+ return menu;
+ }
+ return NULL;
+}
+
+void MenuActions::installSkinOptions(HMENU menu)
+{
+ optionsmenu_wa = 0;
+ HMENU omenu = NULL;
+ if (menu == NULL)
+ {
+ optionsmenu_wa = 1;
+ menu = wa2.getMenuBarMenu(Winamp2FrontEnd::WA2_MAINMENUBAR_OPTIONS);
+ omenu = GetSubMenu(wa2.getPopupMenu(), 11 + wa2.adjustOptionsPopupMenu(0));
+ }
+ int pos2 = 12;
+ int cmdoffset = 0;
+ int pos = optionsmenu_wa ? wa2.adjustFFOptionsMenu(0) + 6 + NUMSTATICWINDOWS /*+ 1*//* + 9*/ : 0;
+ lowest_itempos = pos;
+ int insertedline = 0;
+ if (menu && optionsmenuitems)
+ {
+ int n = MIN(optionsmenuitems->getNumAttributes(), 500);
+ for (int i = 0;i < n;i++)
+ {
+ const wchar_t *attr = optionsmenuitems->enumAttribute(i);
+ if (attr && *attr)
+ {
+ HMENU submenu = NULL;
+ wchar_t txt[256] = {0};
+ optionsmenuitems->getData(attr, txt, 256);
+ GUID g = nsGUID::fromCharW(txt);
+ if (g != INVALID_GUID)
+ { // submenu !
+ submenu = makeSkinOptionsSubMenu(g, &cmdoffset);
+ if (submenu)
+ menulist.addItem(submenu);
+ }
+ int v = optionsmenuitems->getDataAsInt(attr, 0);
+ if (optionsmenu_wa && !insertedline)
+ {
+ wa2.adjustFFOptionsMenu(1);
+ insertedline = 1;
+ InsertMenu(menu, pos++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
+ if (omenu) InsertMenu(omenu, pos2++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
+ }
+ if (optionsmenu_wa) wa2.adjustFFOptionsMenu(1);
+ if (WCSCASEEQLSAFE(txt, L"-"))
+ {
+ InsertMenu(menu, pos++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
+ if (omenu) InsertMenu(omenu, pos2++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
+ }
+ else
+ InsertMenuW(menu, pos++, (v ? MF_CHECKED : MF_UNCHECKED) | MF_STRING | MF_BYPOSITION | (submenu ? MF_POPUP : 0), submenu ? (UINT_PTR)submenu : 44000 + cmdoffset, _(attr));
+ if (omenu) InsertMenuW(omenu, pos2++, (v ? MF_CHECKED : MF_UNCHECKED) | MF_STRING | MF_BYPOSITION | (submenu ? MF_POPUP : 0), submenu ? (UINT_PTR)submenu : 44000 + cmdoffset, _(attr));
+ }
+ cmdoffset++;
+ }
+ ffoptionstop = 44000 + cmdoffset;
+ }
+ // insert colorthemes submenu
+ if (omenu)
+ {
+ PtrListQuickSorted<ColorThemeSlot, ColorThemeSlotSort> sortedthemes;
+ int fn = MIN(WASABI_API_SKIN->colortheme_getNumColorSets(), 500);
+ for (int t = 0;t < fn;t++)
+ sortedthemes.addItem(new ColorThemeSlot(WASABI_API_SKIN->colortheme_enumColorSet(t), t));
+ if (!insertedline)
+ {
+ wa2.adjustFFOptionsMenu(1);
+ InsertMenu(menu, pos++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
+ if (omenu) InsertMenu(omenu, pos2++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
+ }
+ HMENU submenu = CreatePopupMenu();
+ if (WASABI_API_SKIN->colortheme_getNumColorSets() == 0)
+ {
+ InsertMenuW(submenu, 0, MF_GRAYED | MF_STRING | MF_BYPOSITION, 0, WASABI_API_LNGSTRINGW(IDS_NO_THEME_AVAILABLE));
+ }
+ else
+ {
+ int n = sortedthemes.getNumItems();
+ for (int i = 0;i < n;i++)
+ {
+ const wchar_t *ct = sortedthemes.enumItem(i)->name;
+ int entry = sortedthemes.enumItem(i)->entry;
+ int iscurrent = WCSCASEEQLSAFE(ct, WASABI_API_SKIN->colortheme_getColorSet());
+ InsertMenuW(submenu, i, (iscurrent ? MF_CHECKED : MF_UNCHECKED) | MF_STRING | MF_BYPOSITION, 44500 + entry, ct);
+ }
+ }
+ if (optionsmenu_wa) wa2.adjustFFOptionsMenu(1);
+ InsertMenuW(menu, pos++, MF_STRING | MF_BYPOSITION | (submenu ? MF_POPUP : 0), submenu ? (UINT_PTR)submenu : 44000 + cmdoffset, WASABI_API_LNGSTRINGW(IDS_COLOR_THEMES));
+ if (omenu) InsertMenuW(omenu, pos2++, MF_STRING | MF_BYPOSITION | (submenu ? MF_POPUP : 0), submenu ? (UINT_PTR)submenu : 44000 + cmdoffset, WASABI_API_LNGSTRINGW(IDS_COLOR_THEMES));
+ cmdoffset++;
+ sortedthemes.deleteAll();
+ }
+ highest_itempos = pos;
+}
+
+void MenuActions::removeSkinOptions()
+{
+ if (highest_itempos == -1 || !optionsmenu_wa) return ;
+ for (int j = 0;j < menulist.getNumItems();j++)
+ DestroyMenu(menulist.enumItem(j));
+ menulist.removeAll();
+
+ HMENU menu = wa2.getMenuBarMenu(Winamp2FrontEnd::WA2_MAINMENUBAR_OPTIONS);
+ HMENU omenu = GetSubMenu(wa2.getPopupMenu(), 11 + wa2.adjustOptionsPopupMenu(0));
+ if (menu && optionsmenuitems)
+ {
+ for (int i = lowest_itempos;i < highest_itempos;i++)
+ {
+ RemoveMenu(menu, lowest_itempos, MF_BYPOSITION);
+ if (omenu) RemoveMenu(omenu, 12, MF_BYPOSITION);
+ wa2.adjustFFOptionsMenu( -1);
+ }
+ }
+ highest_itempos = -1;
+}
+
+int MenuActions::toggleOption(int n, GUID guid, int *cmdoffset)
+{
+ int _cmdoffset = 0;
+ if (!cmdoffset) cmdoffset = &_cmdoffset;
+ CfgItem *item = NULL;
+ if (guid == INVALID_GUID)
+ item = optionsmenuitems;
+ else
+ item = WASABI_API_CONFIG->config_getCfgItemByGuid(guid);
+
+ if (!item) // not sure why this happens, but it happened in a crash report so I'm going to check for it.
+ return 1; // TODO: guru
+
+ for (int i = 0; i < item->getNumAttributes();i++)
+ {
+ const wchar_t *name = item->enumAttribute(i);
+ if (name && *name)
+ {
+ wchar_t txt[256] = {0};
+ item->getData(name, txt, 256);
+ GUID g = nsGUID::fromCharW(txt);
+ if (g != INVALID_GUID)
+ { // submenu !
+ if (toggleOption(n, g, cmdoffset)) return 1;
+ }
+ if (*cmdoffset == n)
+ {
+ int newv = item->getDataAsInt(name) ? 0 : 1;
+ item->setDataAsInt(name, newv);
+ return 1;
+ }
+ }
+ (*cmdoffset)++;
+ }
+ return 0;
+}
+
+const wchar_t* MenuActions::localizeSkinWindowName(const wchar_t* attr)
+{
+ static wchar_t tweaked_attr[96];
+ ZERO(tweaked_attr);
+
+ // allows us to map some of the common actions to localised versions (primarily with bundled skins)
+ if(!_wcsicmp(attr,L"Equalizer\tAlt+G"))
+ {
+ // if there's a match then we can force things to use the previous menu
+ // string (fixes localisation inconsistancy without altering the scripts!)
+ lstrcpynW(tweaked_attr, eqmenustring, 96);
+ }
+ else if(!_wcsicmp(attr,L"Skin Settings\tAlt+C"))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_SKIN_SETTINGS,tweaked_attr,96);
+ }
+ else if(!_wcsicmp(attr,L"Web Browser\tAlt+X"))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_WEB_BROWSER,tweaked_attr,96);
+ }
+ else if(!_wcsicmp(attr,L"Album Art\tAlt+A"))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_ALBUM_ART,tweaked_attr,96);
+ }
+ else if(!_wcsicmp(attr,L"Color Editor"))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COLOR_EDITOR,tweaked_attr,96);
+ }
+ else
+ {
+ return attr;
+ }
+ return tweaked_attr;
+}
+
+// FIX ME - menu weirdness going on!!
+void MenuActions::installSkinWindowOptions()
+{
+ HMENU menu = wa2.getMenuBarMenu(Winamp2FrontEnd::WA2_MAINMENUBAR_WINDOWS);
+ int pos = lowest_witempos = wa2.adjustFFWindowsMenu(0) + NUMSTATICWINDOWS;
+ HMENU omenu = wa2.getPopupMenu();
+ int pos2 = lowest_witempos2 = wa2.adjustOptionsPopupMenu(0) + 6 + NUMSTATICWINDOWS + 1;
+
+ MENUITEMINFOW mii = {sizeof(mii), };
+ mii.fMask = MIIM_TYPE | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU;
+ mii.fType = MFT_STRING;
+ mii.wID = 42000;
+ mii.dwItemData = 0xD02; // use this as a check so we're only removing the correct items!!
+
+ if (menu && windowsmenuitems)
+ {
+ int n = MIN(windowsmenuitems->getNumAttributes(), 500);
+ int cmdoffset = 0;
+ for (int i = 0;i < n;i++)
+ {
+ const wchar_t *attr = windowsmenuitems->enumAttribute(i);
+
+ if (attr && *attr)
+ {
+ HMENU submenu = NULL;
+ wchar_t txt[256] = {0};
+ windowsmenuitems->getData(attr, txt, 256);
+ GUID g = nsGUID::fromCharW(txt);
+ if (g != INVALID_GUID)
+ { // submenu !
+ submenu = makeSkinOptionsSubMenu(g, &cmdoffset);
+ if (submenu)
+ wmenulist.addItem(submenu);
+ }
+ int v = windowsmenuitems->getDataAsInt(attr, 0);
+ wa2.adjustFFWindowsMenu(1);
+ wa2.adjustOptionsPopupMenu(1);
+
+ attr = localizeSkinWindowName(attr);
+ const wchar_t* t = _(attr);
+ mii.dwTypeData = const_cast<wchar_t *>(t);
+
+ if (WCSCASEEQLSAFE(txt, L"-"))
+ {
+ InsertMenu(menu, pos++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
+ InsertMenu(omenu, pos2++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
+ }
+ else{
+ mii.cch = wcslen(mii.dwTypeData);
+ mii.fState = (v ? MFS_CHECKED : 0);
+ mii.wID = 42000 + cmdoffset;
+ mii.hSubMenu = submenu;
+ InsertMenuItemW(menu, pos++, TRUE, &mii);
+ }
+ InsertMenuItemW(omenu, pos2++, TRUE, &mii);
+ }
+ cmdoffset++;
+ }
+ ffwoptionstop = 42000 + cmdoffset;
+ }
+ highest_witempos = pos;
+ highest_witempos2 = pos2;
+}
+
+void MenuActions::removeSkinWindowOptions()
+{
+ if (highest_witempos == -1) return ;
+ for (int j = 0;j < wmenulist.getNumItems();j++)
+ DestroyMenu(wmenulist.enumItem(j));
+ wmenulist.removeAll();
+
+ HMENU menu = wa2.getMenuBarMenu(Winamp2FrontEnd::WA2_MAINMENUBAR_WINDOWS);
+ HMENU omenu = wa2.getPopupMenu();
+ if (menu && windowsmenuitems)
+ {
+ for(int i = GetMenuItemCount(menu)-1; i != 0; i--)
+ {
+ MENUITEMINFOW info = {sizeof(info), MIIM_DATA, 0, };
+ if(GetMenuItemInfoW(menu,i,TRUE,&info))
+ {
+ if(info.dwItemData == 0xD02){
+ RemoveMenu(menu,i,MF_BYPOSITION);
+ wa2.adjustFFWindowsMenu(-1);
+ }
+ }
+ }
+
+ for(int i = GetMenuItemCount(omenu)-1; i != 0; i--)
+ {
+ MENUITEMINFOW info = {sizeof(info), MIIM_DATA, 0, };
+ if(GetMenuItemInfoW(omenu,i,TRUE,&info))
+ {
+ if(info.dwItemData == 0xD02){
+ RemoveMenu(omenu,i,MF_BYPOSITION);
+ wa2.adjustOptionsPopupMenu(-1);
+ }
+ }
+ }
+
+ /*for (int i = highest_witempos;i >= lowest_witempos;i--)
+ {
+ RemoveMenu(menu, i, MF_BYPOSITION);
+ wa2.adjustFFWindowsMenu(-1);
+ }
+
+ for (int i = highest_witempos2;i >= lowest_witempos2;i--)
+ {
+ RemoveMenu(menu, i, MF_BYPOSITION);
+ wa2.adjustOptionsPopupMenu(-1);
+ }
+ /*/
+ /*for (int i = lowest_witempos;i < highest_witempos;i++)
+ {
+ RemoveMenu(menu, lowest_witempos, MF_BYPOSITION);
+ wa2.adjustFFWindowsMenu(-1);
+ }
+
+ for (int i = lowest_witempos2;i < highest_witempos2;i++)
+ {
+ RemoveMenu(omenu, lowest_witempos2, MF_BYPOSITION);
+ wa2.adjustOptionsPopupMenu(-1);
+ }/**/
+ }
+ highest_witempos = -1;
+ highest_witempos2 = -1;
+}
+
+int MenuActions::toggleWindowOption(int n, GUID guid, int *cmdoffset)
+{
+ int _cmdoffset = 0;
+ if (!cmdoffset) cmdoffset = &_cmdoffset;
+ CfgItem *item = NULL;
+ if (guid == INVALID_GUID)
+ item = windowsmenuitems;
+ else
+ item = WASABI_API_CONFIG->config_getCfgItemByGuid(guid);
+
+ for (int i = 0; i < item->getNumAttributes();i++)
+ {
+ const wchar_t *name = item->enumAttribute(i);
+ if (name && *name)
+ {
+ wchar_t txt[256] = {0};
+ item->getData(name, txt, 256);
+ GUID g = nsGUID::fromCharW(txt);
+ if (g != INVALID_GUID)
+ { // submenu !
+ if (toggleWindowOption(n, g, cmdoffset)) return 1;
+ }
+ if (*cmdoffset == n)
+ {
+ int newv = item->getDataAsInt(name) ? 0 : 1;
+ item->setDataAsInt(name, newv);
+ return 1;
+ }
+ }
+ (*cmdoffset)++;
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/menuactions.h b/Src/Plugins/General/gen_ff/menuactions.h
new file mode 100644
index 00000000..bc940145
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/menuactions.h
@@ -0,0 +1,91 @@
+#ifndef _MENUACTIONS_H
+#define _MENUACTIONS_H
+
+#include <api/service/svcs/svc_action.h>
+
+extern int ffoptionstop;
+extern int ffwoptionstop;
+extern int in_menu;
+
+class MenuActions : public svc_actionI {
+ public :
+ MenuActions();
+ virtual ~MenuActions();
+
+ static const char *getServiceName() { return "Menu Actions"; }
+ virtual int onActionId(int pvtid, const wchar_t *action, const wchar_t *param=NULL, int p1=0, int p2=0, void *data=NULL, int datalen=0, ifc_window *source=NULL);
+
+ static void installSkinOptions(HMENU menu=NULL);
+ static void removeSkinOptions();
+ static int toggleOption(int n, GUID g=INVALID_GUID, int *cmdoffset=NULL);
+
+ static void installSkinWindowOptions();
+ static void removeSkinWindowOptions();
+ static int toggleWindowOption(int n, GUID g=INVALID_GUID, int *cmdoffset=NULL);
+
+ static HMENU makeSkinOptionsSubMenu(GUID g, int *cmdoffset);
+
+ static const wchar_t* localizeSkinWindowName(const wchar_t*);
+
+ enum {
+ _ACTION_MENU = 0,
+ _ACTION_SYSMENU,
+ _ACTION_CONTROLMENU,
+ ACTION_WA5FILEMENU,
+ ACTION_WA5PLAYMENU,
+ ACTION_WA5OPTIONSMENU,
+ ACTION_WA5WINDOWSMENU,
+ ACTION_WA5HELPMENU,
+ ACTION_WA5PEFILEMENU,
+ ACTION_WA5PEPLAYLISTMENU,
+ ACTION_WA5PESORTMENU,
+ ACTION_WA5PEHELPMENU,
+ ACTION_WA5MLFILEMENU,
+ ACTION_WA5MLVIEWMENU,
+ ACTION_WA5MLHELPMENU,
+ ACTION_PEADD,
+ ACTION_PEREM,
+ ACTION_PESEL,
+ ACTION_PEMISC,
+ ACTION_PELIST,
+ ACTION_PELISTOFLISTS,
+ ACTION_VIDFS,
+ ACTION_VID1X,
+ ACTION_VID2X,
+ ACTION_VIDTV,
+ ACTION_VIDMISC,
+ ACTION_VISNEXT,
+ ACTION_VISPREV,
+ ACTION_VISRANDOM,
+ ACTION_VISFS,
+ ACTION_VISCFG,
+ ACTION_VISMENU,
+ ACTION_TRACKINFO,
+ ACTION_TRACKMENU,
+ ACTION_SENDTO,
+ };
+};
+
+
+class ColorThemeSlot
+{
+public:
+ ColorThemeSlot(const wchar_t *_name, int _entry) : name(_name), entry(_entry) {}
+ virtual ~ColorThemeSlot() {}
+ StringW name;
+ int entry;
+};
+
+class ColorThemeSlotSort {
+public:
+ // comparator for sorting
+ static int compareItem(ColorThemeSlot *p1, ColorThemeSlot *p2) {
+ return wcscmp(p1->name, p2->name);
+ }
+ // comparator for searching
+ static int compareAttrib(const wchar_t *attrib, ColorThemeSlot *item) {
+ return wcscmp(attrib, item->name);
+ }
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/minibrowserCOM.cpp b/Src/Plugins/General/gen_ff/minibrowserCOM.cpp
new file mode 100644
index 00000000..e3d896d6
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/minibrowserCOM.cpp
@@ -0,0 +1,93 @@
+#include "precomp__gen_ff.h"
+#include "minibrowserCOM.h"
+
+MinibrowserCOM::MinibrowserCOM(BrowserWnd* brw)
+{
+ this->brw = brw;
+}
+
+HRESULT __stdcall MinibrowserCOM::GetTypeInfoCount(unsigned int FAR* pctinfo)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT __stdcall MinibrowserCOM::GetTypeInfo(unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT __stdcall MinibrowserCOM::GetIDsOfNames( REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgDispId)
+{
+ int notFound = false;
+ for (unsigned int i = 0; i != cNames; i++)
+ {
+ if (!_wcsicmp(rgszNames[i], L"messageToMaki"))
+ {
+ rgDispId[i] = MINIBROWSERCOM_MAKI_MESSAGETOMAKI;
+ continue;
+ }
+ notFound = true;
+ }
+
+ if (!notFound)
+ return S_OK;
+
+ return DISP_E_UNKNOWNNAME;
+}
+
+HRESULT __stdcall MinibrowserCOM::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
+{
+ switch (dispid)
+ {
+ case MINIBROWSERCOM_MAKI_MESSAGETOMAKI:
+ /* var ret = window.external.messageToMaki(str1, str2, int1, int2, int3) */
+ /* keep in mind that the args are passed in reverse order! */
+
+ /*if (wFlags != DISPATCH_METHOD)
+ return DISP_E_MEMBERNOTFOUND;*/
+ if (pdispparams->cArgs != 5)
+ return DISP_E_BADPARAMCOUNT;
+
+ const wchar_t * ret = this->brw->messageToMaki(pdispparams->rgvarg[4].bstrVal, pdispparams->rgvarg[3].bstrVal, pdispparams->rgvarg[2].iVal, pdispparams->rgvarg[1].iVal, pdispparams->rgvarg[0].iVal);
+
+ // (mpdeimos) we need to check this here since in JS one can omit the return value. In this case we would get a NPE here.
+ if (pvarResult != NULL)
+ {
+ BSTR returnValue = SysAllocString(ret);
+ VariantInit(pvarResult);
+ V_VT(pvarResult) = VT_BSTR;
+ V_BSTR(pvarResult) = returnValue;
+ }
+ return S_OK;
+ }
+
+ return DISP_E_MEMBERNOTFOUND;
+}
+
+STDMETHODIMP MinibrowserCOM::QueryInterface(REFIID riid, PVOID *ppvObject)
+{
+ if (!ppvObject)
+ return E_POINTER;
+ else if (IsEqualIID(riid, IID_IDispatch))
+ *ppvObject = (IDispatch *)this;
+ else if (IsEqualIID(riid, IID_IUnknown))
+ *ppvObject = this;
+ else
+ {
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+ }
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG MinibrowserCOM::AddRef(void)
+{
+ return 0;
+}
+
+ULONG MinibrowserCOM::Release(void)
+{
+ return 0;
+}
diff --git a/Src/Plugins/General/gen_ff/minibrowserCOM.h b/Src/Plugins/General/gen_ff/minibrowserCOM.h
new file mode 100644
index 00000000..e237b40f
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/minibrowserCOM.h
@@ -0,0 +1,25 @@
+#pragma once
+#include <ocidl.h>
+#include <api/skin/widgets/mb/iebrowser.h>
+
+class MinibrowserCOM : IDispatch
+{
+public:
+ MinibrowserCOM(BrowserWnd* brw);
+ /** IUnknown */
+ STDMETHOD(QueryInterface)(REFIID riid, PVOID *ppvObject);
+ STDMETHOD_(ULONG, AddRef)(void);
+ STDMETHOD_(ULONG, Release)(void);
+ /** IDispatch */
+ STDMETHOD (GetTypeInfoCount)(unsigned int FAR* pctinfo);
+ STDMETHOD (GetTypeInfo)(unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo);
+ STDMETHOD (GetIDsOfNames)(REFIID riid,LPOLESTR __RPC_FAR *rgszNames,UINT cNames,LCID lcid,DISPID __RPC_FAR *rgDispId);
+ STDMETHOD (Invoke)(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr);
+
+ enum
+ {
+ MINIBROWSERCOM_MAKI_MESSAGETOMAKI = 666,
+ };
+private:
+ BrowserWnd* brw;
+};
diff --git a/Src/Plugins/General/gen_ff/precomp__gen_ff.cpp b/Src/Plugins/General/gen_ff/precomp__gen_ff.cpp
new file mode 100644
index 00000000..26e242df
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/precomp__gen_ff.cpp
@@ -0,0 +1,7 @@
+// precomp__gen_ff.cpp : source file that includes just the standard includes
+// TheLibrary.pch will be the pre-compiled header
+// precomp.obj will contain the pre-compiled type information
+
+#include "precomp__gen_ff.h"
+
+
diff --git a/Src/Plugins/General/gen_ff/precomp__gen_ff.h b/Src/Plugins/General/gen_ff/precomp__gen_ff.h
new file mode 100644
index 00000000..dd83219d
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/precomp__gen_ff.h
@@ -0,0 +1,76 @@
+// precomp__gen_ff.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#ifndef NULLSOFT_GEN_FF_PRECOMP_H
+#define NULLSOFT_GEN_FF_PRECOMP_H
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+#ifndef WINVER
+#define WINVER 0x0501
+#endif
+
+
+// Most used wasabi headers
+
+#include <wasabicfg.h>
+//#include <api.h>
+#include <api__gen_ff.h>
+#include <bfc/platform/platform.h>
+#include <bfc/assert.h>
+#include <bfc/common.h>
+#include <bfc/wasabi_std.h>
+#include <bfc/ptrlist.h>
+#include <bfc/stack.h>
+#include <bfc/tlist.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/string/StringW.h>
+#include <bfc/wasabi_std_wnd.h>
+#include <bfc/std_string.h>
+#include <bfc/dispatch.h>
+#include <bfc/nsGUID.h>
+#include <api/service/servicei.h>
+
+#include <api/service/waservicefactory.h>
+
+#include <api/config/cfgscriptobj.h>
+
+#include <api/wnd/rootwnd.h>
+#include <api/wnd/basewnd.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/objects/guiobject.h>
+
+#include <api/script/scriptobj.h>
+#include <api/script/objcontroller.h>
+#include <api/script/scriptvar.h>
+
+#include "wa2core.h"
+#include "wa2frontend.h"
+#include "wa2wndembed.h"
+
+#include <tataki/canvas/canvas.h>
+#include <tataki/region/region.h>
+#include <tataki/bitmap/bitmap.h>
+
+#include <api/skin/skin.h>
+#include <api/skin/skinparse.h>
+#include <api/skin/widgets.h>
+
+#include <api/timer/timerclient.h>
+
+#include <api/skin/widgets.h>
+
+
+
+#endif // _PRECOMP_H
diff --git a/Src/Plugins/General/gen_ff/prefs.cpp b/Src/Plugins/General/gen_ff/prefs.cpp
new file mode 100644
index 00000000..998d3b50
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/prefs.cpp
@@ -0,0 +1,136 @@
+#include "precomp__gen_ff.h"
+#include "main.h"
+#include "resource.h"
+#include "prefs.h"
+#include "wa2cfgitems.h"
+#include "wa2frontend.h"
+#include "../Agave/Language/api_language.h"
+#include "gen.h"
+#include <commctrl.h>
+#include <windowsx.h>
+
+void turnonoff(HWND wnd, int *t, int n, int v) {
+ for (int i=0;i<n;i++) {
+ EnableWindow(GetDlgItem(wnd, t[i]), v);
+ }
+}
+
+extern void initFFApi();
+extern Wa2CfgItems *cfgitems;
+extern HINSTANCE hInstance;
+
+_int last_page(L"Last Page", 0);
+Wa2FFOptions *ffoptions = NULL;
+HWND subWnd = NULL, tabwnd = NULL;
+int subWndId = -1;
+extern int m_are_we_loaded;
+int toggle_from_wa2 = 0;
+
+void _dosetsel(HWND hwndDlg)
+{
+ tabwnd = GetDlgItem(hwndDlg,IDC_TAB1);
+ int sel=TabCtrl_GetCurSel(tabwnd);
+
+ if (sel >= 0 && (sel != last_page.getValueAsInt() || !subWnd))
+ {
+ last_page.setValueAsInt(sel);
+ if (subWnd) DestroyWindow(subWnd);
+ subWnd = NULL;
+ subWndId = -1;
+
+ UINT t=0;
+ DLGPROC p=0;
+ switch (sel)
+ {
+ case 0: t=IDD_PREFS_GENERAL; p=ffPrefsProc1; subWndId = 0; break;
+ case 1: t=IDD_PREFS_WINDOWS; p=ffPrefsProc4; subWndId = 1; break;
+ case 2: t=IDD_PREFS_FONTS; p=ffPrefsProc2; subWndId = 2; break;
+ case 3: t=IDD_PREFS_THEMES; p=ffPrefsProc3; subWndId = 3; break;
+ case 4: t=IDD_PREFS_SKIN; p=ffPrefsProc5; subWndId = 5; break;
+ }
+ if (t) subWnd=WASABI_API_CREATEDIALOGW(t,hwndDlg,p);
+
+ if (IsWindow(subWnd))
+ {
+ RECT r = {0};
+ GetClientRect(tabwnd,&r);
+ TabCtrl_AdjustRect(tabwnd,FALSE,&r);
+ SetWindowPos(subWnd,HWND_TOP,r.left,r.top,r.right-r.left,r.bottom-r.top,SWP_NOACTIVATE);
+ ShowWindow(subWnd,SW_SHOWNA);
+ }
+
+ if(!SendMessageW(plugin.hwndParent,WM_WA_IPC,IPC_ISWINTHEMEPRESENT,IPC_USE_UXTHEME_FUNC))
+ {
+ SendMessageW(plugin.hwndParent,WM_WA_IPC,(WPARAM)tabwnd,IPC_USE_UXTHEME_FUNC);
+ SendMessageW(plugin.hwndParent,WM_WA_IPC,(WPARAM)subWnd,IPC_USE_UXTHEME_FUNC);
+ }
+ }
+}
+
+#define TabCtrl_InsertItemW(hwnd, iItem, pitem) \
+ (int)SNDMSG((hwnd), TCM_INSERTITEMW, (WPARAM)(int)(iItem), (LPARAM)(const TC_ITEMW *)(pitem))
+
+// frame proc
+INT_PTR CALLBACK ffPrefsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam) {
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ if (WASABI_API_APP == NULL)
+ {
+ // wasabi is not initialized ! we need to init before we can access cfgitems otherwise we'd have
+ // to mirror their values with winamp.ini and that'd be seriously crappy
+ initFFApi();
+ }
+
+ if (!ffoptions)
+ ffoptions = new Wa2FFOptions();
+
+ TCITEMW item = {0};
+ HWND tabwnd=GetDlgItem(hwndDlg,IDC_TAB1);
+ item.mask=TCIF_TEXT;
+ item.pszText=WASABI_API_LNGSTRINGW(IDS_GENERAL);
+ TabCtrl_InsertItemW(tabwnd,0,&item);
+ item.pszText=WASABI_API_LNGSTRINGW(IDS_WINDOW_SETTINGS);
+ TabCtrl_InsertItemW(tabwnd,1,&item);
+ item.pszText=WASABI_API_LNGSTRINGW(IDS_FONT_RENDERING);
+ TabCtrl_InsertItemW(tabwnd,2,&item);
+ if (m_are_we_loaded)
+ {
+ item.pszText=WASABI_API_LNGSTRINGW(IDS_COLOR_THEMES);
+ TabCtrl_InsertItemW(tabwnd,3,&item);
+ item.pszText=WASABI_API_LNGSTRINGW(IDS_CURRENT_SKIN);
+ TabCtrl_InsertItemW(tabwnd,4,&item);
+ }
+
+ TabCtrl_SetCurSel(tabwnd,last_page.getValueAsInt());
+ _dosetsel(hwndDlg);
+ }
+ return 0;
+
+ case WM_NOTIFY:
+ {
+ LPNMHDR p=(LPNMHDR) lParam;
+ if (p->idFrom == IDC_TAB1 && p->code == TCN_SELCHANGE)
+ {
+ _dosetsel(hwndDlg);
+ return 0;
+ }
+ }
+ break;
+
+ case WM_DESTROY:
+ subWnd=NULL;
+ return 0;
+ }
+ return 0;
+}
+
+Wa2FFOptions::Wa2FFOptions() : CfgItemI(L"Winamp5", Wa2FFOptionsGuid) {
+ registerAttribute(&last_page);
+}
+
+int ComboBox_AddStringW(HWND list, const wchar_t *string)
+{
+ return SendMessageW(list, CB_ADDSTRING, 0, (LPARAM)string);
+} \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/prefs.h b/Src/Plugins/General/gen_ff/prefs.h
new file mode 100644
index 00000000..e90aaa33
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/prefs.h
@@ -0,0 +1,30 @@
+#ifndef _FF_PREFS_H
+#define _FF_PREFS_H
+
+#include <api/config/items/cfgitemi.h>
+
+extern INT_PTR CALLBACK ffPrefsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+extern INT_PTR CALLBACK ffPrefsProc1(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+extern INT_PTR CALLBACK ffPrefsProc2(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+extern INT_PTR CALLBACK ffPrefsProc3(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+extern INT_PTR CALLBACK ffPrefsProc4(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+extern INT_PTR CALLBACK ffPrefsProc5(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+
+void _dosetsel(HWND hwndDlg);
+HWND
+ActiveChildWindowFromPoint(HWND hwnd, POINTS cursor_s, const int *controls, size_t controlsCount);
+
+#define WA2FFOPTIONS_PARENT CfgItemI
+
+// {68A2EFD7-0FBB-4ef9-9D3A-590F943C2A73}
+static const GUID Wa2FFOptionsGuid =
+{ 0x68a2efd7, 0xfbb, 0x4ef9, { 0x9d, 0x3a, 0x59, 0xf, 0x94, 0x3c, 0x2a, 0x73 } };
+
+class Wa2FFOptions : public WA2FFOPTIONS_PARENT {
+public:
+ Wa2FFOptions ();
+};
+
+extern Wa2FFOptions *ffoptions;
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/prefs_about.cpp b/Src/Plugins/General/gen_ff/prefs_about.cpp
new file mode 100644
index 00000000..a9e5ca90
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/prefs_about.cpp
@@ -0,0 +1,98 @@
+#include "precomp__gen_ff.h"
+#include "gen.h"
+#include "resource.h"
+#include "menuactions.h"
+#include "wa2frontend.h"
+#include "../Agave/Language/api_language.h"
+
+extern const wchar_t *getSkinInfoW();
+extern int m_are_we_loaded;
+ifc_window *skin_about_group = NULL;
+
+void destroyskinabout()
+{
+ if (skin_about_group)
+ WASABI_API_SKIN->group_destroy(skin_about_group);
+ skin_about_group = NULL;
+}
+
+INT_PTR CALLBACK ffPrefsProc5(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ destroyskinabout();
+ if (m_are_we_loaded)
+ {
+ if (WASABI_API_SKIN->group_exists(L"skin.about.group"))
+ {
+ skin_about_group = WASABI_API_SKIN->group_create(L"skin.about.group");
+ if (skin_about_group)
+ {
+ skin_about_group->setVirtual(0);
+ HWND w = GetDlgItem(hwndDlg, IDC_STATIC_GROUP);
+ skin_about_group->setStartHidden(1);
+ skin_about_group->init(WASABI_API_WND->main_getRootWnd(), 1);
+ SetWindowLong(skin_about_group->gethWnd(), GWL_STYLE, GetWindowLong(skin_about_group->gethWnd(), GWL_STYLE) | WS_CHILD);
+ SetParent(skin_about_group->gethWnd(), w);
+ SetWindowLong(w, GWL_STYLE, GetWindowLong(w, GWL_STYLE) | WS_CLIPCHILDREN);
+ RECT r;
+ GetClientRect(w, &r);
+ skin_about_group->resize(r.left, r.top, r.right - r.left, r.bottom - r.top);
+ skin_about_group->setVisible(1);
+ ShowWindow(skin_about_group->gethWnd(), SW_NORMAL);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_EMPTY), SW_HIDE);
+ }
+ else
+ {
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_EMPTY, WASABI_API_LNGSTRING(IDS_ERROR_WHILE_LOADING_SKIN_WINDOW));
+ }
+ }
+ else
+ {
+ SetDlgItemTextW(hwndDlg, IDC_STATIC_EMPTY, getSkinInfoW());
+ }
+ }
+ else
+ {
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_EMPTY, WASABI_API_LNGSTRING(IDS_NO_SKIN_LOADED));
+ }
+ return 1;
+ case WM_DESTROY:
+ destroyskinabout();
+ break;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDOK: case IDCANCEL:
+ EndDialog(hwndDlg, 0);
+ return 0;
+ case IDC_BUTTON_SKINSPECIFIC:
+ extern void unpopulateWindowsMenus();
+ extern TList<HMENU> menulist;
+ HMENU menu = CreatePopupMenu();
+ unpopulateWindowsMenus();
+ MenuActions::installSkinOptions(menu);
+ menulist.addItem(menu);
+ HWND w = GetDlgItem(hwndDlg, IDC_BUTTON_SKINSPECIFIC);
+ RECT r;
+ GetWindowRect(w, &r);
+ int n = GetMenuItemCount(menu);
+ if (n == 1)
+ {
+ HMENU submenu = GetSubMenu(menu, 0);
+ if (submenu != NULL) menu = submenu;
+ }
+ else if (n == 0)
+ {
+ InsertMenuW(menu, 0, MF_BYPOSITION | MF_STRING | MF_GRAYED, 0, WASABI_API_LNGSTRINGW(IDS_NO_OPTIONS_AVAILABLE_FOR_THIS_SKIN));
+ }
+ //DoTrackPopup(menu, TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, r.left, r.top, wa2.getMainWindow());
+ TrackPopupMenu(menu, TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, r.left, r.top, 0, wa2.getMainWindow(), NULL);
+ MenuActions::removeSkinOptions();
+ return 0;
+ }
+ break;
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/prefs_alpha.cpp b/Src/Plugins/General/gen_ff/prefs_alpha.cpp
new file mode 100644
index 00000000..54b21b29
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/prefs_alpha.cpp
@@ -0,0 +1,280 @@
+#include "precomp__gen_ff.h"
+#include "resource.h"
+#include "prefs.h"
+#include "wa2cfgitems.h"
+#include <bfc/wasabi_std_wnd.h>
+#include "../Agave/Language/api_language.h"
+#include <api/skin/skinparse.h>
+#include <commctrl.h>
+void turnonoff(HWND wnd, int *t, int n, int v);
+extern int toggle_from_wa2;
+int opacity_all_on[] = {IDC_SLIDER_CUSTOMALPHA, IDC_STATIC_TRANSP, IDC_STATIC_ALPHA, IDC_STATIC_OPAQUE, IDC_COMBO_OPACITY};
+int opacity_all_off[] = {IDC_CHECK_LINKALPHA, };
+int opacity_unavail[] = {IDC_STATIC_OPACITY, IDC_CHECK_LINKALLALPHA, IDC_COMBO_OPACITY, IDC_SLIDER_CUSTOMALPHA,
+ IDC_STATIC_TRANSP,IDC_STATIC_ALPHA,IDC_STATIC_OPAQUE,IDC_CHECK_LINKALPHA,IDC_STATIC_AUTOON,
+ IDC_STATIC_AUTOONTXT,IDC_STATIC_FADEIN2,IDC_SLIDER_FADEIN,IDC_STATIC_FADEIN,IDC_STATIC_HOLD2,
+ IDC_SLIDER_HOLD,IDC_STATIC_HOLD,IDC_STATIC_FADEOUT2,IDC_SLIDER_FADEOUT,IDC_STATIC_FADEOUT,
+ IDC_STATIC_EXTENDBOX,IDC_EDIT_EXTEND,IDC_STATIC_EXTEND,IDC_SPIN_EXTEND};
+static int ratio_all_on[] = {IDC_SLIDER_CUSTOMSCALE, IDC_COMBO_SCALE, IDC_STATIC_SCALE};
+static int ratio_all_off[] = {IDC_CHECK_LINKRATIO, };
+static int spin_extend = 0;
+
+static UINT get_logslider(HWND wnd) {
+ int z = SendMessageW(wnd, TBM_GETPOS, 0, 0);
+ long a = (long)(0.5 + 303.03 * pow(100.0, (double)z/30303.0) - 303.03);
+ return a;
+}
+
+void set_logslider(HWND wnd, int b) {
+ long a = (long) (0.5 + 30303.0 * log((double)(b+303.0)/303.03)/log(100.0));
+ SendMessageW(wnd, TBM_SETPOS, 1, a);
+}
+
+int ResizeComboBoxDropDown(HWND hwndDlg, UINT id, const wchar_t * str, int width) {
+ SIZE size = {0};
+ HWND control = (id ? GetDlgItem(hwndDlg, id) : hwndDlg);
+ HDC hdc = GetDC(control);
+ // get and select parent dialog's font so that it'll calculate things correctly
+ HFONT font = (HFONT)SendMessageW((id ? hwndDlg : GetParent(hwndDlg)), WM_GETFONT, 0, 0),
+ oldfont = (HFONT)SelectObject(hdc, font);
+ GetTextExtentPoint32W(hdc, str, lstrlenW(str)+1, &size);
+
+ int ret = width;
+ if(size.cx > width)
+ {
+ if (id)
+ SendDlgItemMessageW(hwndDlg, id, CB_SETDROPPEDWIDTH, size.cx, 0);
+ else
+ SendMessageW(hwndDlg, CB_SETDROPPEDWIDTH, size.cx, 0);
+
+ ret = size.cx;
+ }
+
+ SelectObject(hdc, oldfont);
+ ReleaseDC(control, hdc);
+ return ret;
+}
+
+INT_PTR CALLBACK ffPrefsProc4(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam) {
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ {
+ spin_extend = 0;
+
+ int transpavail = Wasabi::Std::Wnd::isTransparencyAvailable();
+ if (!transpavail) turnonoff(hwndDlg, opacity_unavail, sizeof(opacity_unavail)/sizeof(int), 0);
+ CheckDlgButton(hwndDlg, IDC_CHECK_LINKALPHA, cfg_uioptions_linkalpha.getValueAsInt());
+ CheckDlgButton(hwndDlg, IDC_CHECK_LINKALLALPHA, cfg_uioptions_linkallalpha.getValueAsInt());
+ Layout *main = SkinParser::getMainLayout();
+ int curalpha = 255;
+ if (main) {
+ if (!WASABI_API_WND->rootwndIsValid(main)) { return 0; }
+ curalpha = cfg_uioptions_linkedalpha.getValueAsInt();
+ }
+ int v = (int)((curalpha / 255.0f * 100.0f)+0.5f);
+ wchar_t msStr[16] = {0};
+ WASABI_API_LNGSTRINGW_BUF(IDS_MS,msStr,16);
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SLIDER_CUSTOMALPHA),TBM_SETRANGEMAX,0,100);
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SLIDER_CUSTOMALPHA),TBM_SETRANGEMIN,0,10);
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SLIDER_CUSTOMALPHA),TBM_SETPOS,1,v);
+
+ wchar_t *name = 0;
+ SendDlgItemMessageW(hwndDlg, IDC_COMBO_OPACITY, CB_ADDSTRING, 0, (LPARAM)(name = WASABI_API_LNGSTRINGW(IDS_OPAQUE_FOCUS)));
+ int width = ResizeComboBoxDropDown(hwndDlg, IDC_COMBO_OPACITY, name, 0);
+ SendDlgItemMessageW(hwndDlg, IDC_COMBO_OPACITY, CB_SETITEMDATA, 0, 2);
+ SendDlgItemMessageW(hwndDlg, IDC_COMBO_OPACITY, CB_ADDSTRING, 0, (LPARAM)(name = WASABI_API_LNGSTRINGW(IDS_OPAQUE_HOVER)));
+ width = ResizeComboBoxDropDown(hwndDlg, IDC_COMBO_OPACITY, name, width);
+ SendDlgItemMessageW(hwndDlg, IDC_COMBO_OPACITY, CB_SETITEMDATA, 1, 1);
+ SendDlgItemMessageW(hwndDlg, IDC_COMBO_OPACITY, CB_ADDSTRING, 0, (LPARAM)(name = WASABI_API_LNGSTRINGW(IDS_NO_OPACITY)));
+ ResizeComboBoxDropDown(hwndDlg, IDC_COMBO_OPACITY, name, width);
+ SendDlgItemMessageW(hwndDlg, IDC_COMBO_OPACITY, CB_SETITEMDATA, 2, 0);
+
+ int item = 2;
+ switch(cfg_uioptions_autoopacitylinked.getValueAsInt())
+ {
+ case 1:
+ item = 1;
+ break;
+ case 2:
+ item = 0;
+ break;
+ default:
+ item = 2;
+ break;
+ }
+ SendDlgItemMessageW(hwndDlg, IDC_COMBO_OPACITY, CB_SETCURSEL, item, 0);
+
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_ALPHA, StringPrintf("%d%%", v));
+ turnonoff(hwndDlg, opacity_all_on, sizeof(opacity_all_on)/sizeof(int), cfg_uioptions_linkallalpha.getValueAsInt() && transpavail);
+ turnonoff(hwndDlg, opacity_all_off, sizeof(opacity_all_off)/sizeof(int), !cfg_uioptions_linkallalpha.getValueAsInt() && transpavail);
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SLIDER_HOLD),TBM_SETRANGEMAX,0,30303);
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SLIDER_HOLD),TBM_SETRANGEMIN,0,0);
+ set_logslider(GetDlgItem(hwndDlg,IDC_SLIDER_HOLD),cfg_uioptions_autoopacitytime.getValueAsInt());
+ SetDlgItemTextW(hwndDlg, IDC_STATIC_HOLD, StringPrintfW(L"%d%s", cfg_uioptions_autoopacitytime.getValueAsInt(),msStr));
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SLIDER_FADEIN),TBM_SETRANGEMAX,0,30303);
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SLIDER_FADEIN),TBM_SETRANGEMIN,0,0);
+ set_logslider(GetDlgItem(hwndDlg,IDC_SLIDER_FADEIN),cfg_uioptions_autoopacityfadein.getValueAsInt());
+ SetDlgItemTextW(hwndDlg, IDC_STATIC_FADEIN, StringPrintfW(L"%d%s", cfg_uioptions_autoopacityfadein.getValueAsInt(),msStr));
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SLIDER_FADEOUT),TBM_SETRANGEMAX,0,30303);
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SLIDER_FADEOUT),TBM_SETRANGEMIN,0,0);
+ set_logslider(GetDlgItem(hwndDlg,IDC_SLIDER_FADEOUT),cfg_uioptions_autoopacityfadeout.getValueAsInt());
+ SetDlgItemTextW(hwndDlg, IDC_STATIC_FADEOUT, StringPrintfW(L"%d%s", cfg_uioptions_autoopacityfadeout.getValueAsInt(),msStr));
+
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SPIN_EXTEND),UDM_SETRANGE,0,MAKELONG(100,0));
+ SetDlgItemInt(hwndDlg, IDC_EDIT_EXTEND, cfg_uioptions_extendautoopacity.getValueAsInt(), FALSE);
+
+ CheckDlgButton(hwndDlg, IDC_CHECK_LINKALLRATIO, cfg_uioptions_linkallratio.getValueAsInt());
+ CheckDlgButton(hwndDlg, IDC_CHECK_LINKRATIO, cfg_uioptions_linkratio.getValueAsInt());
+
+ SendDlgItemMessageW(hwndDlg, IDC_COMBO_SCALE, CB_ADDSTRING, 0, (LPARAM)(name = WASABI_API_LNGSTRINGW(IDS_USELOCK)));
+ width = ResizeComboBoxDropDown(hwndDlg, IDC_COMBO_SCALE, name, 0);
+ SendDlgItemMessageW(hwndDlg, IDC_COMBO_SCALE, CB_ADDSTRING, 0, (LPARAM)(name = WASABI_API_LNGSTRINGW(IDS_ALLLOCKED)));
+ ResizeComboBoxDropDown(hwndDlg, IDC_COMBO_SCALE, name, width);
+ SendDlgItemMessageW(hwndDlg, IDC_COMBO_SCALE, CB_SETCURSEL, !!cfg_uioptions_uselocks.getValueAsInt(), 0);
+
+ int oldscale = 1;
+ if (main)
+ {
+ if (!WASABI_API_WND->rootwndIsValid(main)) { return 0; }
+ oldscale = (int)main->getRenderRatio();
+ }
+ int u = (int)((oldscale * 100.0f) + 0.5f);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_CUSTOMSCALE), TBM_SETRANGEMAX, 0, 300);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_CUSTOMSCALE), TBM_SETRANGEMIN, 0, 10);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_CUSTOMSCALE), TBM_SETPOS, 1, u);
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_SCALE, StringPrintf("%d%%", u));
+ turnonoff(hwndDlg, ratio_all_on, sizeof(ratio_all_on) / sizeof(int), cfg_uioptions_linkallratio.getValueAsInt());
+ turnonoff(hwndDlg, ratio_all_off, sizeof(ratio_all_off) / sizeof(int), !cfg_uioptions_linkallratio.getValueAsInt());
+
+ spin_extend = 1;
+ return 1;
+ }
+ case WM_HSCROLL:
+ {
+ char msStr[16] = {0};
+ WASABI_API_LNGSTRING_BUF(IDS_MS,msStr,16);
+ HWND ctrl = (HWND)lParam;
+ int t=(int)SendMessageW((HWND) lParam,TBM_GETPOS,0,0);
+ if (ctrl == GetDlgItem(hwndDlg,IDC_SLIDER_CUSTOMALPHA)) {
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_ALPHA, StringPrintf("%d%%", t));
+ int v = (int)(t / 100.0 * 255 + 0.5);
+ if (v == 254) v = 255;
+ cfg_uioptions_linkedalpha.setValueAsInt(v);
+ }
+ else if (ctrl == GetDlgItem(hwndDlg, IDC_SLIDER_HOLD)) {
+ t = get_logslider(ctrl);
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_HOLD, StringPrintf("%d%s", t, msStr));
+ cfg_uioptions_autoopacitytime.setValueAsInt(t);
+ }
+ else if (ctrl == GetDlgItem(hwndDlg, IDC_SLIDER_FADEIN)) {
+ t = get_logslider(ctrl);
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_FADEIN, StringPrintf("%d%s", t, msStr));
+ cfg_uioptions_autoopacityfadein.setValueAsInt(t);
+ }
+ else if (ctrl == GetDlgItem(hwndDlg, IDC_SLIDER_FADEOUT)) {
+ int t = get_logslider(ctrl);
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_FADEOUT, StringPrintf("%d%s", t, msStr));
+ cfg_uioptions_autoopacityfadeout.setValueAsInt(t);
+ }
+ else if (ctrl == GetDlgItem(hwndDlg, IDC_SLIDER_CUSTOMSCALE))
+ {
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_SCALE, StringPrintf("%d%%", t));
+ Layout *main = SkinParser::getMainLayout();
+ if (main)
+ {
+ main->setRenderRatio((float)t / 100.0);
+ if (cfg_uioptions_linkratio.getValueAsInt())
+ {
+ int nc = SkinParser::getNumContainers();
+ for (int i = 0;i < nc;i++)
+ {
+ Container *c = SkinParser::enumContainer(i);
+ if (c)
+ {
+ int nl = c->getNumLayouts();
+ for (int j = 0;j < nl;j++)
+ {
+ Layout *l = c->enumLayout(j);
+ if (l)
+ {
+ UpdateWindow(l->gethWnd());
+ }
+ }
+ }
+ }
+ }
+ }
+ return 0;
+ }
+ break;
+ }
+ case WM_COMMAND:
+ toggle_from_wa2 = 1;
+ switch (LOWORD(wParam)) {
+ case IDC_CHECK_LINKALPHA:
+ cfg_uioptions_linkalpha.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_CHECK_LINKALPHA));
+ return 0;
+ case IDC_CHECK_LINKALLALPHA:
+ cfg_uioptions_linkallalpha.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_CHECK_LINKALLALPHA));
+ turnonoff(hwndDlg, opacity_all_on, sizeof(opacity_all_on)/sizeof(int), cfg_uioptions_linkallalpha.getValueAsInt());
+ turnonoff(hwndDlg, opacity_all_off, sizeof(opacity_all_off)/sizeof(int), !cfg_uioptions_linkallalpha.getValueAsInt());
+ return 0;
+ case IDC_EDIT_EXTEND:
+ if (HIWORD(wParam) == EN_CHANGE && spin_extend) {
+ int t, a = GetDlgItemInt(hwndDlg,IDC_EDIT_EXTEND,&t,0);
+ if (t) cfg_uioptions_extendautoopacity.setValueAsInt(MAX(a,0));
+ if (a < 0)
+ {
+ char msStr[16] = {0};
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_HOLD,
+ StringPrintf("%d%s", cfg_uioptions_autoopacitytime.getValueAsInt(),WASABI_API_LNGSTRING_BUF(IDS_MS,msStr,16)));
+ }
+ }
+ return 0;
+ case IDC_CHECK_LINKALLRATIO:
+ cfg_uioptions_linkallratio.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_CHECK_LINKALLRATIO));
+ turnonoff(hwndDlg, ratio_all_on, sizeof(ratio_all_on) / sizeof(int), cfg_uioptions_linkallratio.getValueAsInt());
+ turnonoff(hwndDlg, ratio_all_off, sizeof(ratio_all_off) / sizeof(int), !cfg_uioptions_linkallratio.getValueAsInt());
+ return 0;
+ case IDC_COMBO_OPACITY:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ {
+ int sel = SendDlgItemMessageW(hwndDlg, IDC_COMBO_OPACITY, CB_GETCURSEL, 0, 0);
+ if (sel != CB_ERR)
+ {
+ cfg_uioptions_autoopacitylinked.setValueAsInt(SendDlgItemMessageW(hwndDlg, IDC_COMBO_OPACITY, CB_GETITEMDATA, sel, 0));
+ }
+ }
+ return 0;
+ case IDC_COMBO_SCALE:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ {
+ int sel = SendDlgItemMessageW(hwndDlg, IDC_COMBO_SCALE, CB_GETCURSEL, 0, 0);
+ if (sel != CB_ERR)
+ {
+ cfg_uioptions_uselocks.setValueAsInt(!!sel);
+ }
+ }
+ return 0;
+ case IDC_CHECK_LINKRATIO:
+ cfg_uioptions_linkratio.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_CHECK_LINKRATIO));
+ return 0;
+ }
+ case WM_DESTROY:
+ spin_extend = 0;
+ return 0;
+ }
+
+ const int controls[] =
+ {
+ IDC_SLIDER_CUSTOMALPHA,
+ IDC_SLIDER_HOLD,
+ IDC_SLIDER_FADEIN,
+ IDC_SLIDER_FADEOUT,
+ IDC_SLIDER_CUSTOMSCALE,
+ };
+ if (FALSE != WASABI_API_APP->DirectMouseWheel_ProcessDialogMessage(hwndDlg, uMsg, wParam, lParam, controls, ARRAYSIZE(controls)))
+ return TRUE;
+
+ return 0;
+} \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/prefs_colorthemes.cpp b/Src/Plugins/General/gen_ff/prefs_colorthemes.cpp
new file mode 100644
index 00000000..9c8a5333
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/prefs_colorthemes.cpp
@@ -0,0 +1,101 @@
+#include "precomp__gen_ff.h"
+#include "resource.h"
+#include <windowsx.h>
+
+extern int m_are_we_loaded;
+extern int toggle_from_wa2;
+extern HWND subWnd;
+
+#define ListBox_AddStringW(hwndCtl, lpsz) ((int)(DWORD)SendMessageW((hwndCtl), LB_ADDSTRING, 0L, (LPARAM)(LPCWSTR)(lpsz)))
+#define ListBox_FindStringW(hwndCtl, indexStart, lpszFind) ((int)(DWORD)SendMessageW((hwndCtl), LB_FINDSTRING, (WPARAM)(int)(indexStart), (LPARAM)(LPCWSTR)(lpszFind)))
+#define ListBox_GetTextW(hwndCtl, index, lpszBuffer) ((int)(DWORD)SendMessageW((hwndCtl), LB_GETTEXT, (WPARAM)(int)(index), (LPARAM)(LPWSTR)(lpszBuffer)))
+#define ListBox_GetItemDataW(hwndCtl, index) ((LRESULT)(ULONG_PTR)SendMessageW((hwndCtl), LB_GETITEMDATA, (WPARAM)(int)(index), 0L))
+#define ListBox_SetItemDataW(hwndCtl, index, data) ((int)(DWORD)SendMessageW((hwndCtl), LB_SETITEMDATA, (WPARAM)(int)(index), (LPARAM)(data)))
+
+
+static void fillColorThemesList(HWND list)
+{
+ ListBox_ResetContent(list);
+ if (!m_are_we_loaded) return ;
+ int numsets = WASABI_API_SKIN->colortheme_getNumColorSets();
+ for (int i = 0; i < numsets; i++)
+ {
+ const wchar_t *set = WASABI_API_SKIN->colortheme_enumColorSet(i);
+ if (!_wcsnicmp(set, L"{coloredit}", 11))
+ {
+ int pos = ListBox_AddStringW(list, set + 11);
+ ListBox_SetItemDataW(list, pos, 1);
+ }
+ else
+ {
+ ListBox_AddStringW(list, set);
+ }
+ }
+ const wchar_t *curset = WASABI_API_SKIN->colortheme_getColorSet();
+ int cur = ListBox_FindStringW(list, 0, curset);
+ ListBox_SetCurSel(list, cur);
+}
+
+INT_PTR CALLBACK ffPrefsProc3(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_NOTIFYFORMAT:
+ return NFR_UNICODE;
+ case WM_INITDIALOG:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_SETTHEME), m_are_we_loaded);
+ {
+ HWND listWindow;
+ listWindow = GetDlgItem(hwndDlg, IDC_LIST1);
+ if (NULL != listWindow)
+ {
+ EnableWindow(listWindow, m_are_we_loaded);
+ fillColorThemesList(listWindow);
+ if (NULL != WASABI_API_APP)
+ WASABI_API_APP->DirectMouseWheel_EnableConvertToMouseWheel(listWindow, TRUE);
+ }
+ }
+ return 1;
+ case WM_COMMAND:
+ {
+ toggle_from_wa2 = 1;
+ int id = (int) LOWORD(wParam);
+ int msg = (int)HIWORD(wParam);
+ if (id == IDC_LIST1 && msg == LBN_DBLCLK || id == IDC_BUTTON_SETTHEME)
+ {
+ HWND ctrl = GetDlgItem(hwndDlg, IDC_LIST1);
+ int sel = ListBox_GetCurSel(ctrl);
+ if (sel != -1)
+ {
+ wchar_t newset[256 + 11] = L"";
+ ListBox_GetTextW(ctrl, sel, newset);
+ newset[255] = 0;
+ if (*newset)
+ {
+ int p = ListBox_GetItemDataW(ctrl, sel);
+ if (p)
+ {
+ WCSCPYN(newset, StringPrintfW(L"{coloredit}%s", newset), 256 + 11);
+ }
+ WASABI_API_SKIN->colortheme_setColorSet(newset);
+ }
+ }
+ return 0;
+ }
+ toggle_from_wa2 = 0;
+ break;
+ }
+ case WM_DESTROY:
+ subWnd = NULL;
+ if (NULL != WASABI_API_APP)
+ {
+ HWND listWindow;
+ listWindow = GetDlgItem(hwndDlg, IDC_LIST1);
+ if (NULL != listWindow)
+ WASABI_API_APP->DirectMouseWheel_EnableConvertToMouseWheel(listWindow, FALSE);
+ }
+ return 0;
+ }
+ return 0;
+}
+
diff --git a/Src/Plugins/General/gen_ff/prefs_font.cpp b/Src/Plugins/General/gen_ff/prefs_font.cpp
new file mode 100644
index 00000000..ccb5c586
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/prefs_font.cpp
@@ -0,0 +1,860 @@
+#include "precomp__gen_ff.h"
+#include <commctrl.h>
+#include <windows.h>
+#include <windowsx.h>
+#include "resource.h"
+#include <api/font/font.h>
+#include <bfc/parse/paramparser.h>
+#include "../nu/ListView.h"
+#include "prefs.h"
+#include "gen.h"
+#include "wa2cfgitems.h"
+#include <api/font/win32/truetypefont_win32.h>
+#include "../Agave/Language/api_language.h"
+
+extern HWND subWnd;
+#define ComboBox_SetItemDataW(hwndCtl, index, data) ((int)(DWORD)SendMessageW((hwndCtl), CB_SETITEMDATA, (WPARAM)(int)(index), (LPARAM)(data)))
+#define ComboBox_GetLBTextLenW(hwndCtl, index) ((int)(DWORD)SendMessageW((hwndCtl), CB_GETLBTEXTLEN, (WPARAM)(int)(index), 0L))
+#define ComboBox_GetLBTextW(hwndCtl, index, lpszBuffer) ((int)(DWORD)SendMessageW((hwndCtl), CB_GETLBTEXT, (WPARAM)(int)(index), (LPARAM)(LPCWSTR)(lpszBuffer)))
+#define ComboBox_SelectStringW(hwndCtl, indexStart, lpszSelect) ((int)(DWORD)SendMessageW((hwndCtl), CB_SELECTSTRING, (WPARAM)(int)(indexStart), (LPARAM)(LPCWSTR)(lpszSelect)))
+
+static W_ListView mappingList;
+int fonts_loaded = 0;
+int ComboBox_AddStringW(HWND list, const wchar_t *string);
+
+class font_entry
+{
+public:
+ StringW filename;
+ StringW face;
+};
+
+class font_entry_comparator1
+{
+public:
+ // comparator for sorting
+ static int compareItem(font_entry *p1, font_entry* p2)
+ {
+ return wcscmp(p1->face, p2->face);
+ }
+ // comparator for searching
+ static int compareAttrib(const wchar_t *attrib, font_entry *item)
+ {
+ return wcscmp(attrib, item->face);
+ }
+};
+class font_entry_comparator2
+{
+public:
+ // comparator for sorting
+ static int compareItem(font_entry *p1, font_entry* p2)
+ {
+ return _wcsicmp(p1->filename, p2->filename);
+ }
+ // comparator for searching
+ static int compareAttrib(const wchar_t *attrib, font_entry *item)
+ {
+ return _wcsicmp(attrib, item->filename);
+ }
+};
+
+int ResizeComboBoxDropDown(HWND hwndDlg, UINT id, const wchar_t * str, int width);
+
+PtrListQuickSorted<font_entry, font_entry_comparator1> fontlist;
+PtrListQuickSorted<font_entry, font_entry_comparator2> fontlist_byfilename;
+
+PtrListQuickSorted<font_entry, font_entry_comparator1> skin_fontlist;
+PtrListQuickSorted<font_entry, font_entry_comparator2> skin_fontlist_byfilename;
+
+void fillFontLists(HWND list, HWND list2, int selectdefault = 1)
+{
+ fontlist.deleteAll();
+ fontlist_byfilename.removeAll();
+
+ ComboBox_ResetContent(list);
+ ComboBox_ResetContent(list2);
+ SendMessageW(list, CB_INITSTORAGE, 400, 32);
+ SendMessageW(list2, CB_INITSTORAGE, 400, 32);
+
+ wchar_t *txt = WMALLOC(WA_MAX_PATH);
+ Wasabi::Std::getFontPath(WA_MAX_PATH, txt);
+ StringW path = txt;
+ StringW deffont = cfg_options_ttfoverridefont.getValue();
+ FREE(txt);
+ StringPathCombine mask(path, L"*.ttf");
+ WIN32_FIND_DATAW fd = {0};
+ HANDLE fh;
+ int width = 0, width2 = 0;
+ if ((fh = FindFirstFileW(mask, &fd)) != INVALID_HANDLE_VALUE)
+ {
+ while (1)
+ {
+ StringW fullpath = fd.cFileName;
+ if (_wcsicmp(fullpath, L".") && _wcsicmp(fullpath, L".."))
+ {
+ fullpath = StringPathCombine(path, fullpath);
+ StringW fontname = TrueTypeFont_Win32::filenameToFontFace(fullpath);
+ if (!fontname.isempty())
+ {
+ if (fontlist_byfilename.findItem(fd.cFileName)) continue;
+ font_entry *fe = new font_entry;
+ fe->face = fontname;
+ fe->filename = fd.cFileName;
+ fontlist.addItem(fe);
+ fontlist_byfilename.addItem(fe);
+ int idx = ComboBox_AddStringW(list, fontname);
+ ComboBox_SetItemData(list, idx, fe);
+ width = ResizeComboBoxDropDown(list, 0, fontname, width);
+
+ idx = ComboBox_AddStringW(list2, fontname);
+ ComboBox_SetItemData(list2, idx, fe);
+ width2 = ResizeComboBoxDropDown(list2, 0, fontname, width2);
+ }
+ }
+ if (!FindNextFileW(fh, &fd)) break;
+ }
+ }
+ if (fh != INVALID_HANDLE_VALUE) FindClose(fh);
+ int pos = -1;
+ font_entry *fe = fontlist_byfilename.findItem(deffont.v(), NULL);
+ if (fe)
+ {
+ fontlist.sort(1);
+ pos = fontlist.searchItem(fe);
+ }
+ ComboBox_SetCurSel(list, pos);
+}
+
+
+int fm_validMapping(HWND wnd)
+{
+ if (ComboBox_GetCurSel(GetDlgItem(wnd, IDC_COMBO_SKINFONTS)) == -1) return 0;
+ if (ComboBox_GetCurSel(GetDlgItem(wnd, IDC_COMBO_FONTS)) == -1) return 0;
+ return 1;
+}
+
+int fm_hasSelection(HWND wnd)
+{
+ int n = mappingList.GetCount();
+ for (int i = 0;i < n;i++)
+ if (mappingList.GetSelected(i))
+ return 1;
+ return 0;
+}
+
+void fm_itemClicked(HWND wnd, int pos)
+{
+ HWND combo1 = GetDlgItem(wnd, IDC_COMBO_SKINFONTS);
+ HWND combo2 = GetDlgItem(wnd, IDC_COMBO_FONTS);
+
+ int n = mappingList.GetCount();
+ for (int i = 0;i < n;i++)
+ {
+ if (mappingList.GetSelected(i))
+ {
+ wchar_t txt[4096] = {0};
+ mappingList.GetText(i, 0, txt, 4096);
+ ComboBox_SetCurSel(combo1, -1);
+ if (skin_fontlist.findItem(txt))
+ ComboBox_SelectStringW(combo1, -1, StringPrintfW(L" %s", txt));
+ else
+ ComboBox_SelectStringW(combo1, -1, txt);
+ mappingList.GetText(i, 1, txt, 4096);
+
+ ComboBox_SetCurSel(combo2, -1);
+ ComboBox_SelectStringW(combo2, -1, txt);
+
+ wchar_t type[64] = {0};
+ mappingList.GetText(i, 3, type, 64);
+
+ CheckDlgButton(wnd, IDC_RADIO_THISSKIN, WCSCASEEQLSAFE(type, WASABI_API_LNGSTRINGW(IDS_THIS_SKIN)));
+ CheckDlgButton(wnd, IDC_RADIO_ALLSKINS, !WCSCASEEQLSAFE(type, WASABI_API_LNGSTRINGW(IDS_THIS_SKIN)));
+
+ wchar_t scale[64] = {0};
+ mappingList.GetText(i, 2, scale, 64);
+ int s = WTOI(scale);
+ SendMessageW(GetDlgItem(wnd, IDC_SLIDER_SCALE), TBM_SETPOS, 1, s);
+ SetDlgItemTextW(wnd, IDC_STATIC_SCALE, StringPrintfW(L"%d%%", s));
+ break;
+ }
+ }
+ EnableWindow(GetDlgItem(wnd, IDC_BUTTON_SET), fm_validMapping(wnd) && fm_hasSelection(wnd));
+ EnableWindow(GetDlgItem(wnd, IDC_BUTTON_NEW), fm_validMapping(wnd));
+ EnableWindow(GetDlgItem(wnd, IDC_BUTTON_DEL), fm_hasSelection(wnd));
+}
+
+void fm_invalidate()
+{
+ Font::uninstallAll(1);
+ WASABI_API_WNDMGR->wndTrackInvalidateAll();
+}
+
+void fm_scanMapping(HWND ctrl, const wchar_t *id)
+{
+ int global = 0;
+ wchar_t t[256] = L"";
+ int scale;
+ StringW tmp;
+ tmp.printf(L"Skin:%s/Font Mapping/%s", WASABI_API_SKIN->getSkinName(), id);
+ WASABI_API_CONFIG->getStringPrivate(tmp, t, 250, L"");
+
+ tmp.printf(L"Skin:%s/Font Mapping/%s_scale", WASABI_API_SKIN->getSkinName(), id);
+ scale = WASABI_API_CONFIG->getIntPrivate(tmp, -1);
+
+ if (!*t)
+ {
+ global = 1;
+ tmp.printf(L"Font Mapping/%s", id);
+ WASABI_API_CONFIG->getStringPrivate(tmp, t, 250, L"");
+ tmp.printf(L"Skin:%s/Font Mapping/%s_scale", WASABI_API_SKIN->getSkinName(), id);
+ scale = WASABI_API_CONFIG->getIntPrivate(tmp, -1);
+ }
+ if (t && *t)
+ {
+ if (!WCSCASESTR(t, L".ttf")) wcscat(t, L".ttf");
+ font_entry *fe = fontlist_byfilename.findItem(t);
+ if (fe)
+ {
+ int pos = mappingList.InsertItem(0, id, 0);
+ mappingList.SetItemText(pos, 1, fe->face.getValue());
+ mappingList.SetItemText(pos, 2, StringPrintfW(L"%d%%", scale != -1 ? scale : 100).getValue());
+ mappingList.SetItemText(pos, 3, WASABI_API_LNGSTRINGW(global ? IDS_ALL_SKINS : IDS_THIS_SKIN));
+ }
+ }
+}
+
+void fm_rescanList(HWND lv)
+{
+ mappingList.Clear();
+
+ wchar_t t[4096] = L"";
+ WASABI_API_CONFIG->getStringPrivate(StringPrintfW(L"Skin:%s/Font Mapping/Mapped", WASABI_API_SKIN->getSkinName()), t, 4096, L"");
+ ParamParser pp(t);
+ for (int i = 0;i < pp.getNumItems();i++)
+ {
+ fm_scanMapping(lv, pp.enumItem(i));
+ }
+ WASABI_API_CONFIG->getStringPrivate(L"Font Mapping/Mapped", t, 4096, L"");
+ ParamParser pp2(t);
+ for (int i = 0;i < pp2.getNumItems();i++)
+ {
+ fm_scanMapping(lv, pp2.enumItem(i));
+ }
+}
+
+void fm_saveMappingLists(HWND wnd)
+{
+ PtrListQuickSorted<StringW, StringWComparator> global_list;
+ PtrListQuickSorted<StringW, StringWComparator> skin_list;
+
+ int n = mappingList.GetCount();
+ for (int i = 0;i < n;i++)
+ {
+ wchar_t txt[4096] = {0};
+ mappingList.GetText(i, 0, txt, 4096);
+
+ wchar_t type[64] = {0};
+ mappingList.GetText(i, 3, type, 64);
+
+ if (!_wcsicmp(type, WASABI_API_LNGSTRINGW(IDS_THIS_SKIN)))
+ {
+ if (skin_list.findItem(txt) != NULL) continue;
+ skin_list.addItem(new StringW(txt));
+ }
+ else
+ {
+ if (global_list.findItem(txt) != NULL) continue;
+ global_list.addItem(new StringW(txt));
+ }
+ }
+ StringW s = L"";
+ foreach(global_list)
+ if (!s.isempty())
+ s += L";";
+ s += global_list.getfor()->getValue();
+ endfor;
+ WASABI_API_CONFIG->setStringPrivate(L"Font Mapping/Mapped", s);
+
+ s = L"";
+ foreach(skin_list)
+ if (!s.isempty()) s += L";";
+ s += skin_list.getfor()->getValue();
+ endfor;
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"Skin:%s/Font Mapping/Mapped", WASABI_API_SKIN->getSkinName()), s);
+
+ global_list.deleteAll();
+ skin_list.deleteAll();
+}
+
+void fm_delMapping(HWND wnd, int pos = -1)
+{
+ HWND list = GetDlgItem(wnd, IDC_LIST_MAPPINGS);
+ int n = mappingList.GetCount();
+ int start = 0;
+ if (pos != -1) { start = pos; n = pos + 1; }
+ for (int i = start;i < n;i++)
+ {
+ if (pos != -1 || mappingList.GetSelected(i))
+ {
+ wchar_t txt[4096] = {0};
+ mappingList.GetText(i, 0, txt, 4096);
+
+ wchar_t m[64] = {0};
+ mappingList.GetText(i, 3, m, 64);
+
+ if (WCSCASEEQLSAFE(m, WASABI_API_LNGSTRINGW(IDS_THIS_SKIN)))
+ {
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"Skin:%s/Font Mapping/%s", WASABI_API_SKIN->getSkinName(), txt), L"");
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"Skin:%s/Font Mapping/%s_scale", WASABI_API_SKIN->getSkinName(), txt), L"100");
+ }
+ else
+ {
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"Font Mapping/%s", txt), L"");
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"Font Mapping/%s_scale", txt), L"100");
+ }
+ mappingList.DeleteItem(i);
+ break;
+ }
+ }
+ fm_saveMappingLists(wnd);
+ fm_rescanList(list);
+ fm_invalidate();
+ if (pos == -1)
+ {
+ EnableWindow(GetDlgItem(wnd, IDC_BUTTON_DEL), 0);
+ EnableWindow(GetDlgItem(wnd, IDC_BUTTON_SET), 0);
+ }
+}
+
+void fm_newMapping(HWND wnd)
+{
+ HWND combo1 = GetDlgItem(wnd, IDC_COMBO_SKINFONTS);
+ HWND combo2 = GetDlgItem(wnd, IDC_COMBO_FONTS);
+ int global = !IsDlgButtonChecked(wnd, IDC_RADIO_THISSKIN);
+
+ int pos = ComboBox_GetCurSel(combo1);
+ int l = ComboBox_GetLBTextLenW(combo1, pos);
+ wchar_t *txt = WMALLOC(l + 1);
+ ComboBox_GetLBTextW(combo1, pos, txt);
+ if (!*txt)
+ {
+ FREE(txt);
+ return ;
+ }
+ wchar_t *delme = txt;
+ if (*txt == ' ') txt++;
+ font_entry *fe = skin_fontlist.findItem(txt);
+ if (!fe) fe = fontlist.findItem(txt);
+ if (!fe) return ;
+ FREE(delme);
+
+
+ int n = mappingList.GetCount();
+ int oldpos = -1;
+ for (int i = 0;i < n;i++)
+ {
+ wchar_t txt[4096] = {0};
+ mappingList.GetText(i, 0, txt, 4096);
+ if (!_wcsicmp(fe->face, txt)) { oldpos = i; break; }
+ }
+
+ if (oldpos != -1) fm_delMapping(wnd, oldpos);
+
+ pos = ComboBox_GetCurSel(combo2);
+ l = ComboBox_GetLBTextLenW(combo2, pos);
+ txt = WMALLOC(l + 1);
+ ComboBox_GetLBTextW(combo2, pos, txt);
+ if (!*txt)
+ {
+ FREE(txt);
+ return ;
+ }
+ font_entry *femap = fontlist.findItem(txt);
+ if (!femap) return ;
+ FREE(txt);
+
+ StringW file = femap->filename;
+
+ int v = (int)SendMessageW(GetDlgItem(wnd, IDC_SLIDER_SCALE), TBM_GETPOS, 0, 0);
+
+ if (!global)
+ {
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"Skin:%s/Font Mapping/%s", WASABI_API_SKIN->getSkinName(), fe->face), file);
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"Skin:%s/Font Mapping/%s_scale", WASABI_API_SKIN->getSkinName(), fe->face), v);
+ }
+ else
+ {
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"Font Mapping/%s", fe->face), file);
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"Font Mapping/%s_scale", fe->face), v);
+ }
+
+ fm_scanMapping(GetDlgItem(wnd, IDC_LIST_MAPPINGS), fe->face);
+ fm_saveMappingLists(wnd);
+ fm_invalidate();
+
+ if (oldpos == -1)
+ {
+ int n = mappingList.GetCount();
+ for (int i = 0;i < n;i++)
+ {
+ wchar_t txt[4096] = {0};
+ mappingList.GetText(i, 0, txt, 4096);
+ if (!_wcsicmp(fe->face, txt)) { oldpos = i; break; }
+ }
+ }
+
+ if (oldpos != -1)
+ {
+ mappingList.SetSelected(oldpos);
+ EnableWindow(GetDlgItem(wnd, IDC_BUTTON_DEL), 1);
+ EnableWindow(GetDlgItem(wnd, IDC_BUTTON_SET), 1);
+ }
+}
+
+void fm_modifyMapping(HWND wnd)
+{
+ int n = mappingList.GetCount();
+ int i;
+ for (i = 0;i < n;i++)
+ {
+ if (mappingList.GetSelected(i))
+ {
+ wchar_t txt[4096] = {0};
+ mappingList.GetText(i, 0, txt, 4096);
+
+ wchar_t m[64] = {0};
+ mappingList.GetText(i, 3, m, 64);
+
+ if (WCSCASEEQLSAFE(m, WASABI_API_LNGSTRINGW(IDS_THIS_SKIN)))
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"Skin:%s/Font Mapping/%s", WASABI_API_SKIN->getSkinName(), txt), L"");
+ else
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"Font Mapping/%s", txt), L"");
+ mappingList.DeleteItem(i);
+ break;
+ }
+ }
+ if (i == n) return ;
+ fm_newMapping(wnd);
+ mappingList.SetSelected(i);
+}
+
+void fillFontList2(HWND list, int reset = 1)
+{
+ if (reset)
+ ComboBox_ResetContent(list);
+
+ int width = 0;
+ foreach(fontlist)
+ const wchar_t *str;
+ int idx = ComboBox_AddStringW(list, (str = fontlist.getfor()->face.v()));
+ ComboBox_SetItemDataW(list, idx, fontlist.getfor());
+ width = ResizeComboBoxDropDown(list, 0, str, width);
+ endfor;
+}
+
+void fillSkinFontList(HWND list)
+{
+ ComboBox_ResetContent(list);
+ SendMessageW(list, CB_INITSTORAGE, 400, 32);
+ skin_fontlist.deleteAll();
+ skin_fontlist_byfilename.removeAll();
+ int n = Font::getNumFontDefs();
+ for (int i = 0;i < n;i++)
+ {
+ FontDef *fd = Font::enumFontDef(i);
+ if (!fd) continue;
+ if (!fd->allowmapping) continue;
+ font_entry *fe = new font_entry;
+ fe->filename = fd->filename;
+ fe->face = fd->id;
+ skin_fontlist.addItem(fe);
+ skin_fontlist_byfilename.addItem(fe);
+ int idx = ComboBox_AddStringW(list, StringPrintfW(L" %s", fe->face));
+ ComboBox_SetItemDataW(list, idx, fe);
+ }
+ fillFontList2(list, 0);
+}
+
+VOID CALLBACK FontMappingLoader(HWND hwndDlg, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ KillTimer(hwndDlg, idEvent);
+
+ HWND ctrl = GetDlgItem(hwndDlg, IDC_COMBO_FONTS);
+ HWND ctrl2 = GetDlgItem(hwndDlg, IDC_COMBO_SKINFONTS);
+
+ fillFontList2(ctrl, 1);
+ fillSkinFontList(ctrl2);
+
+ EnableWindow(ctrl, TRUE);
+ EnableWindow(ctrl2, TRUE);
+}
+
+BOOL CALLBACK fontMapperProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ HWND lv = GetDlgItem(hwndDlg, IDC_LIST_MAPPINGS);
+ mappingList.setwnd(lv);
+
+ mappingList.AddCol(WASABI_API_LNGSTRINGW(IDS_FONT), 140);
+ mappingList.AddCol(WASABI_API_LNGSTRINGW(IDS_MAPPING), 139);
+ mappingList.AddCol(WASABI_API_LNGSTRINGW(IDS_SCALE), 48);
+ mappingList.AddCol(WASABI_API_LNGSTRINGW(IDS_TYPE), 64);
+
+ HWND ctrl = GetDlgItem(hwndDlg, IDC_COMBO_FONTS);
+ ComboBox_AddStringW(ctrl, WASABI_API_LNGSTRINGW(IDS_LOADING));
+ ComboBox_SetCurSel(ctrl, 0);
+ EnableWindow(ctrl, FALSE);
+ ctrl = GetDlgItem(hwndDlg, IDC_COMBO_SKINFONTS);
+ ComboBox_AddStringW(ctrl, WASABI_API_LNGSTRINGW(IDS_LOADING));
+ ComboBox_SetCurSel(ctrl, 0);
+ EnableWindow(ctrl, FALSE);
+ SetTimer(hwndDlg, 0xC0DF, 1, FontMappingLoader);
+
+ fm_rescanList(lv);
+ CheckDlgButton(hwndDlg, IDC_RADIO_THISSKIN, 1);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_DEL), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_NEW), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_SET), 0);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_SCALE), TBM_SETRANGEMAX, 0, 200);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_SCALE), TBM_SETRANGEMIN, 0, 25);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_SCALE), TBM_SETPOS, 1, 100);
+ return 1;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDCANCEL:
+ EndDialog(hwndDlg, 0);
+ return 0;
+ case IDOK:
+ EndDialog(hwndDlg, 1);
+ return 0;
+ case IDC_BUTTON_NEW:
+ fm_newMapping(hwndDlg);
+ return 0;
+ case IDC_BUTTON_DEL:
+ fm_delMapping(hwndDlg);
+ return 0;
+ case IDC_BUTTON_SET:
+ fm_modifyMapping(hwndDlg);
+ return 0;
+ case IDC_COMBO_FONTS:
+ case IDC_COMBO_SKINFONTS:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_SET), fm_validMapping(hwndDlg) && fm_hasSelection(hwndDlg));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_NEW), fm_validMapping(hwndDlg));
+ return 0;
+ }
+ case WM_HSCROLL:
+ {
+ if ((HWND) lParam == GetDlgItem(hwndDlg, IDC_SLIDER_SCALE))
+ {
+ int t = (int)SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_SCALE), TBM_GETPOS, 0, 0);
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_SCALE, StringPrintf("%d%%", t));
+ return 0;
+ }
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ int ctrl = (int)wParam;
+ NMHDR *pnmh = (NMHDR*)lParam;
+ if (ctrl == IDC_LIST_MAPPINGS)
+ {
+ if (pnmh->code == NM_CLICK)
+ {
+ NMLISTVIEW *nml = (NMLISTVIEW*)lParam;
+ fm_itemClicked(hwndDlg, nml->iItem);
+ break;
+ }
+ }
+ }
+ }
+
+ const int controls[] =
+ {
+ IDC_SLIDER_SCALE,
+ };
+ if (FALSE != WASABI_API_APP->DirectMouseWheel_ProcessDialogMessage(hwndDlg, uMsg, wParam, lParam, controls, ARRAYSIZE(controls)))
+ return TRUE;
+
+ return 0;
+}
+
+void updateBFReplacement(HWND hwndDlg)
+{
+ int replace = !IsDlgButtonChecked(hwndDlg, IDC_CHECK_ALLOWBITMAPFONTS);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_COMBO_TTFOVERRIDE), (replace && fonts_loaded));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SLIDER_SCALETTFOVERRIDE), replace);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC_DECREASESIZE), replace);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC_TTFSCALE), replace);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC_INCREASESIZE), replace);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NO_7BIT_OVERRIDE), replace);
+}
+
+void updateFreetypeVisible(HWND hwndDlg)
+{
+ if (!IsDlgButtonChecked(hwndDlg, IDC_CHECK_FREETYPETTF))
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC_CHARMAP), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_COMBO_CHARMAP), FALSE);
+ }
+ else
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC_CHARMAP), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_COMBO_CHARMAP), TRUE);
+ }
+}
+
+
+void updateAltFontsVisible(HWND hwndDlg)
+{
+ if (!IsDlgButtonChecked(hwndDlg, IDC_CHECK_ALTFONTS))
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK_NO_ALT_7BIT_OVERRIDE), FALSE);
+ }
+ else
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK_NO_ALT_7BIT_OVERRIDE), TRUE);
+ }
+}
+
+// {504060F6-7D8C-4ebe-AE1D-A8BDF5EA1881}
+static const GUID freetypeFontRendererGUID =
+{ 0x504060f6, 0x7d8c, 0x4ebe, { 0xae, 0x1d, 0xa8, 0xbd, 0xf5, 0xea, 0x18, 0x81 } };
+
+VOID CALLBACK FontLoader(HWND hwndDlg, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ KillTimer(hwndDlg, idEvent);
+
+ HWND ctrl = GetDlgItem(hwndDlg, IDC_COMBO_TTFOVERRIDE);
+ HWND ctrl2 = GetDlgItem(hwndDlg, IDC_COMBO_DEFAULTFONT);
+
+ fillFontLists(ctrl, ctrl2);
+
+ int pos = -1;
+ font_entry *fe = fontlist_byfilename.findItem(cfg_options_ttfoverridefont.getValue(), NULL);
+ if (fe)
+ {
+ fontlist.sort(1);
+ pos = fontlist.searchItem(fe);
+ }
+ ComboBox_SetCurSel(ctrl, pos);
+
+ pos = -1;
+ fe = fontlist_byfilename.findItem(cfg_options_defaultfont.getValue(), NULL);
+ if (fe)
+ {
+ fontlist.sort(1);
+ pos = fontlist.searchItem(fe);
+ }
+ ComboBox_SetCurSel(ctrl2, pos);
+
+ EnableWindow(ctrl, (!IsDlgButtonChecked(hwndDlg, IDC_CHECK_ALLOWBITMAPFONTS)));
+ EnableWindow(ctrl2, TRUE);
+ EnableWindow(ctrl2, TRUE);
+ fonts_loaded = 1;
+}
+
+INT_PTR CALLBACK ffPrefsProc2(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ fonts_loaded = 0;
+
+ CheckDlgButton(hwndDlg, IDC_CHECK_ALLOWBITMAPFONTS, cfg_options_allowbitmapfonts.getValueAsInt());
+ CheckDlgButton(hwndDlg, IDC_CHECK_ALTFONTS, cfg_options_altfonts.getValueAsInt());
+
+ // delay the loading of the font lists until after the dialog has loaded to improve ui response
+ HWND ctrl = GetDlgItem(hwndDlg, IDC_COMBO_TTFOVERRIDE);
+ ComboBox_AddStringW(ctrl, WASABI_API_LNGSTRINGW(IDS_LOADING));
+ ComboBox_SetCurSel(ctrl, 0);
+ EnableWindow(ctrl, FALSE);
+
+ ctrl = GetDlgItem(hwndDlg, IDC_COMBO_DEFAULTFONT);
+ ComboBox_AddStringW(ctrl, WASABI_API_LNGSTRINGW(IDS_LOADING));
+ ComboBox_SetCurSel(ctrl, 0);
+ EnableWindow(ctrl, FALSE);
+ SetTimer(hwndDlg, 0xC0DE, 1, FontLoader);
+
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_SCALETTFOVERRIDE), TBM_SETRANGEMAX, 0, 200);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_SCALETTFOVERRIDE), TBM_SETRANGEMIN, 0, 25);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_SCALETTFOVERRIDE), TBM_SETPOS, 1, cfg_options_ttfoverridescale.getValueAsInt());
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_TTFSCALE, StringPrintf("%d%%", cfg_options_ttfoverridescale.getValueAsInt()));
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_SCALEDEFAULTFONT), TBM_SETRANGEMAX, 0, 200);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_SCALEDEFAULTFONT), TBM_SETRANGEMIN, 0, 25);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_SCALEDEFAULTFONT), TBM_SETPOS, 1, cfg_options_defaultfontscale.getValueAsInt());
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_SCALEDEFAULTFONT, StringPrintf("%d%%", cfg_options_defaultfontscale.getValueAsInt()));
+
+ HWND charmaps = GetDlgItem(hwndDlg, IDC_COMBO_CHARMAP);
+ if (WASABI_API_SVC->service_getServiceByGuid(freetypeFontRendererGUID) == 0) // no freetype
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC_FREETYPE), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK_FREETYPETTF), FALSE);
+ EnableWindow(charmaps, FALSE);
+ }
+ else
+ {
+ const wchar_t *v = cfg_options_fontrenderer.getValue();
+ CheckDlgButton(hwndDlg, IDC_CHECK_FREETYPETTF, WCSCASEEQLSAFE(v, L"FreeType"));
+
+ ComboBox_AddStringW(charmaps, WASABI_API_LNGSTRINGW(IDS_AUTO_UNICODE_LATIN1_ASCII));
+ ComboBox_AddStringW(charmaps, L"Unicode");
+ ComboBox_AddStringW(charmaps, L"Apple Roman");
+ ComboBox_AddStringW(charmaps, L"Adobe Latin-1");
+ ComboBox_AddStringW(charmaps, L"Adobe Standard");
+ ComboBox_AddStringW(charmaps, L"Adobe Custom");
+ ComboBox_AddStringW(charmaps, L"Adobe Expert");
+ ComboBox_AddStringW(charmaps, L"SJIS");
+ ComboBox_AddStringW(charmaps, L"Big5");
+ ComboBox_AddStringW(charmaps, L"Wansung");
+ ComboBox_AddStringW(charmaps, L"Johab");
+ ComboBox_SetCurSel(charmaps, cfg_options_freetypecharmap.getValueAsInt() + 1);
+ }
+
+ CheckDlgButton(hwndDlg, IDC_NO_7BIT_OVERRIDE, cfg_options_no7bitsttfoverride.getValueAsInt());
+ CheckDlgButton(hwndDlg, IDC_CHECK_NO_ALT_7BIT_OVERRIDE, cfg_options_noalt7bitsttfoverride.getValueAsInt());
+
+ updateBFReplacement(hwndDlg);
+ updateFreetypeVisible(hwndDlg);
+ updateAltFontsVisible(hwndDlg);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_FONTMAPPER), cfg_options_usefontmapper.getValueAsInt());
+ CheckDlgButton(hwndDlg, IDC_CHECK_USEFONTMAPPER, cfg_options_usefontmapper.getValueAsInt());
+ return 1;
+ }
+ case WM_COMMAND:
+ {
+ int id = (int) LOWORD(wParam);
+ int msg = (int)HIWORD(wParam);
+ switch (id)
+ {
+ case IDC_CHECK_ALLOWBITMAPFONTS:
+ updateBFReplacement(hwndDlg);
+ cfg_options_allowbitmapfonts.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_CHECK_ALLOWBITMAPFONTS));
+ return 0;
+ case IDC_CHECK_ALTFONTS:
+ updateAltFontsVisible(hwndDlg);
+ cfg_options_altfonts.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_CHECK_ALTFONTS));
+ return 0;
+ case IDC_CHECK_FREETYPETTF:
+ updateFreetypeVisible(hwndDlg);
+ if (!IsDlgButtonChecked(hwndDlg, IDC_CHECK_FREETYPETTF))
+ cfg_options_fontrenderer.setValue(L"Win32 TextOut");
+ else
+ cfg_options_fontrenderer.setValue(L"FreeType");
+ return 0;
+ case IDC_NO_7BIT_OVERRIDE:
+ cfg_options_no7bitsttfoverride.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_NO_7BIT_OVERRIDE));
+ return 0;
+ case IDC_CHECK_NO_ALT_7BIT_OVERRIDE:
+ cfg_options_noalt7bitsttfoverride.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_CHECK_NO_ALT_7BIT_OVERRIDE));
+ return 0;
+ case IDC_BUTTON_FONTMAPPER:
+ WASABI_API_DIALOGBOXW(IDD_FONTMAPPER, hwndDlg, fontMapperProc);
+ return 0;
+ case IDC_CHECK_USEFONTMAPPER:
+ cfg_options_usefontmapper.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_CHECK_USEFONTMAPPER));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_FONTMAPPER), cfg_options_usefontmapper.getValueAsInt());
+ return 0;
+ case IDC_COMBO_TTFOVERRIDE:
+ {
+ if (msg == CBN_SELCHANGE)
+ {
+ HWND list = GetDlgItem(hwndDlg, IDC_COMBO_TTFOVERRIDE);
+ int idx = ComboBox_GetCurSel(list);
+ if (idx != -1)
+ {
+ font_entry *fe = (font_entry *)ComboBox_GetItemData(list, idx);
+ if (fe && fontlist.haveItem(fe))
+ {
+ cfg_options_ttfoverridefont.setValue(fe->filename);
+ }
+ }
+ return 0;
+ }
+ }
+ case IDC_COMBO_DEFAULTFONT:
+ {
+ if (msg == CBN_SELCHANGE)
+ {
+ HWND list = GetDlgItem(hwndDlg, IDC_COMBO_DEFAULTFONT);
+ int idx = ComboBox_GetCurSel(list);
+ if (idx != -1)
+ {
+ font_entry *fe = (font_entry *)ComboBox_GetItemData(list, idx);
+ if (fe && fontlist.haveItem(fe))
+ {
+ cfg_options_defaultfont.setValue(fe->filename);
+ }
+ }
+ return 0;
+ }
+ }
+ case IDC_COMBO_CHARMAP:
+ {
+ if (msg == CBN_SELCHANGE)
+ {
+ int idx = ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_COMBO_CHARMAP));
+ if (idx >= 0)
+ {
+ cfg_options_freetypecharmap.setValueAsInt(idx - 1);
+ }
+ return 0;
+ }
+ }
+ }
+ break;
+ }
+ case WM_HSCROLL:
+ {
+ if ((HWND) lParam == GetDlgItem(hwndDlg, IDC_SLIDER_SCALETTFOVERRIDE))
+ {
+ int t = (int)SendMessageW((HWND)lParam, TBM_GETPOS, 0, 0);
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_TTFSCALE, StringPrintf("%d%%", t));
+ SetTimer(hwndDlg, 100, 100, NULL);
+ return 0;
+ }
+ if ((HWND) lParam == GetDlgItem(hwndDlg, IDC_SLIDER_SCALEDEFAULTFONT))
+ {
+ int t = (int)SendMessageW((HWND)lParam, TBM_GETPOS, 0, 0);
+ SetDlgItemTextA(hwndDlg, IDC_STATIC_SCALEDEFAULTFONT, StringPrintf("%d%%", t));
+ SetTimer(hwndDlg, 101, 100, NULL);
+ return 0;
+ }
+ break;
+ }
+ case WM_TIMER:
+ {
+ if (wParam == 100)
+ {
+ KillTimer(hwndDlg, 100);
+ int t = (int)SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_SCALETTFOVERRIDE), TBM_GETPOS, 0, 0);
+ cfg_options_ttfoverridescale.setValueAsInt(t);
+ }
+ else if (wParam == 101)
+ {
+ KillTimer(hwndDlg, 101);
+ int t = (int)SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_SCALEDEFAULTFONT), TBM_GETPOS, 0, 0);
+ cfg_options_defaultfontscale.setValueAsInt(t);
+ }
+ return 0;
+ }
+ case WM_DESTROY:
+ subWnd = NULL;
+ return 0;
+ }
+
+ const int controls[] =
+ {
+ IDC_SLIDER_SCALETTFOVERRIDE,
+ IDC_SLIDER_SCALEDEFAULTFONT,
+ };
+ if (FALSE != WASABI_API_APP->DirectMouseWheel_ProcessDialogMessage(hwndDlg, uMsg, wParam, lParam, controls, ARRAYSIZE(controls)))
+ return TRUE;
+
+ return 0;
+}
diff --git a/Src/Plugins/General/gen_ff/prefs_general.cpp b/Src/Plugins/General/gen_ff/prefs_general.cpp
new file mode 100644
index 00000000..1c5ab1dc
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/prefs_general.cpp
@@ -0,0 +1,273 @@
+#include "precomp__gen_ff.h"
+#include "resource.h"
+#include <commctrl.h>
+#include "wa2cfgitems.h"
+#include "gen.h"
+#include "prefs.h"
+#include "../Agave/Language/api_language.h"
+#include <api/skin/skinparse.h>
+
+void turnonoff(HWND wnd, int *t, int n, int v);
+extern int toggle_from_wa2;
+extern HWND subWnd;
+
+static int auto_res = -1;
+static int cur_res = 10;
+static DWORD cur_res_last = 0;
+static int cur_res_total = 0;
+static int cur_res_num = 0;
+static int old_res = 0;
+static int dock_dist = 0;
+static int dock_dist2 = 0;
+static int spin_inc = 0;
+static int spin_show = 0;
+static int spin_hide = 0;
+int desktopalpha_unavail[] = {IDC_STATIC_DA1, IDC_CHECK_DESKTOPALPHA};
+
+static const wchar_t *getScrollTextSpeedW(float v)
+{
+ int skipn = (int)((1.0f / v) - 1 + 0.5f);
+ static wchar_t buf[64];
+ ZERO(buf);
+ switch (skipn)
+ {
+ case 0: return WASABI_API_LNGSTRINGW_BUF(IDS_FASTER, buf, 64);
+ case 1: return WASABI_API_LNGSTRINGW_BUF(IDS_FAST, buf, 64);
+ case 2: return WASABI_API_LNGSTRINGW_BUF(IDS_AVERAGE, buf, 64);
+ case 3: return WASABI_API_LNGSTRINGW_BUF(IDS_SLOW, buf, 64);
+ case 4: return WASABI_API_LNGSTRINGW_BUF(IDS_SLOWER, buf, 64);
+ }
+ return WASABI_API_LNGSTRINGW_BUF(IDS_N_A, buf, 64);
+}
+
+static void nextRes(HWND dlg)
+{
+ if (cur_res == 250)
+ {
+ cfg_uioptions_timerresolution.setValueAsInt(old_res);
+ SetDlgItemTextW(dlg, IDC_TXT, WASABI_API_LNGSTRINGW(IDS_FAILED_TO_DETECT_OPTIMAL_RESOLUTION));
+ }
+ else
+ {
+ if (cur_res >= 100)
+ cur_res += 5;
+ else if (cur_res >= 50)
+ cur_res += 2;
+ else
+ cur_res++;
+ SetDlgItemTextW(dlg, IDC_TXT, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_AUTO_DETECTING), cur_res));
+ cur_res_last = Wasabi::Std::getTickCount();
+ cur_res_total = 0;
+ cur_res_num = 0;
+ SetTimer(dlg, 1, cur_res, NULL);
+ }
+}
+
+static INT_PTR CALLBACK autoTimerResProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ old_res = cfg_uioptions_timerresolution.getValueAsInt();
+ cur_res = -1;
+ return 1;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDCANCEL:
+ cfg_uioptions_timerresolution.setValueAsInt(old_res);
+ EndDialog(hwndDlg, 0);
+ return 0;
+ case IDOK:
+ if (cur_res == -1)
+ {
+ cfg_uioptions_timerresolution.setValueAsInt(250);
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
+ SetDlgItemTextW(hwndDlg, IDC_TXT, WASABI_API_LNGSTRINGW(IDS_PREPARING_AUTO_DETECTION));
+ SetTimer(hwndDlg, 2, 1000, NULL);
+ }
+ else EndDialog(hwndDlg, IDOK);
+ return 0;
+ }
+ break;
+ case WM_TIMER:
+ {
+ if (wParam == 1)
+ {
+ DWORD now = Wasabi::Std::getTickCount();
+ cur_res_total += now - cur_res_last;
+ cur_res_num++;
+ cur_res_last = now;
+ int m = 5;
+ if (cur_res >= 100) m = 2;
+ else if (cur_res >= 50) m = 3;
+ if (cur_res_num == m)
+ {
+ float average = (float)cur_res_total / (float)m;
+ if (average <= (float)cur_res*1.1)
+ {
+ auto_res = cur_res;
+ cfg_uioptions_timerresolution.setValueAsInt(old_res);
+ SetDlgItemTextW(hwndDlg, IDC_TXT, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_AUTO_DETECTION_SUCCESSFUL), cur_res));
+ SetDlgItemTextW(hwndDlg, IDOK, WASABI_API_LNGSTRINGW(IDS_ACCEPT));
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
+ }
+ else
+ {
+ nextRes(hwndDlg);
+ }
+ }
+ return 0;
+ }
+ else if (wParam == 2)
+ {
+ KillTimer(hwndDlg, 2);
+ cur_res = 9;
+ nextRes(hwndDlg);
+ return 0;
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+static void autoTimerRes(HWND dlg)
+{
+ INT_PTR r = WASABI_API_DIALOGBOXW(IDD_AUTOTIMERRES, dlg, autoTimerResProc);
+ if (r == IDOK)
+ {
+ cfg_uioptions_timerresolution.setValueAsInt(auto_res);
+ SendMessageW(GetDlgItem(dlg, IDC_SLIDER_TIMERRESOLUTION), TBM_SETPOS, 1, auto_res);
+ SetDlgItemTextW(dlg, IDC_STATIC_TIMERRES, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_TIMERS_RESOLUTION), auto_res));
+ }
+}
+
+INT_PTR CALLBACK ffPrefsProc1(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ dock_dist = dock_dist2 = spin_inc = spin_show = spin_hide = 0;
+
+ CheckDlgButton(hwndDlg, IDC_CHECK_DESKTOPALPHA, cfg_uioptions_desktopalpha.getValueAsInt());
+ if (!Wasabi::Std::Wnd::isDesktopAlphaAvailable()) turnonoff(hwndDlg, desktopalpha_unavail, sizeof(desktopalpha_unavail)/sizeof(int), 0);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_TIMERRESOLUTION), TBM_SETRANGEMAX, 0, 250);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_TIMERRESOLUTION), TBM_SETRANGEMIN, 0, 10);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_TIMERRESOLUTION), TBM_SETPOS, 1, cfg_uioptions_timerresolution.getValueAsInt());
+ SetDlgItemTextW(hwndDlg, IDC_STATIC_TIMERRES, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_TIMERS_RESOLUTION), cfg_uioptions_timerresolution.getValueAsInt()));
+ CheckDlgButton(hwndDlg, IDC_CHECK_TOOLTIPS, cfg_uioptions_tooltips.getValueAsInt());
+ CheckDlgButton(hwndDlg, IDC_CHECK_DOCKING, cfg_options_docking.getValueAsInt());
+ CheckDlgButton(hwndDlg, IDC_CHECK_DOCKING2, cfg_options_appbarondrag.getValueAsInt());
+
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SPIN_DOCKDISTANCE),UDM_SETRANGE,0,MAKELONG(1000,0));
+ SetDlgItemInt(hwndDlg, IDC_EDIT_DOCKDISTANCE, cfg_options_dockingdistance.getValueAsInt(), 0);
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SPIN_DOCKDISTANCE2),UDM_SETRANGE,0,MAKELONG(1000,0));
+ SetDlgItemInt(hwndDlg, IDC_EDIT_DOCKDISTANCE2, cfg_options_appbardockingdistance.getValueAsInt(), 0);
+
+ SetDlgItemTextA(hwndDlg, IDC_EDIT_INCREMENT, StringPrintf("%d", cfg_uioptions_textincrement.getValueAsInt()));
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_TICKERSPEED), TBM_SETRANGEMAX, 0, 4);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_TICKERSPEED), TBM_SETRANGEMIN, 0, 0);
+ SendMessageW(GetDlgItem(hwndDlg, IDC_SLIDER_TICKERSPEED), TBM_SETPOS, 1, (int)(1.0f / cfg_uioptions_textspeed.getValueAsDouble() - 1.0f + 0.5f));
+ SetDlgItemTextW(hwndDlg, IDC_STATIC_TICKER, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_TEXT_SCROLL_SPEED), getScrollTextSpeedW((float)cfg_uioptions_textspeed.getValueAsDouble())));
+
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SPIN_SHOWTIME),UDM_SETRANGE,0,MAKELONG(9999,0));
+ SetDlgItemInt(hwndDlg, IDC_EDIT_SHOWTIME, cfg_uioptions_appbarsshowtime.getValueAsInt(), 0);
+ SendMessageW(GetDlgItem(hwndDlg,IDC_SPIN_HIDETIME),UDM_SETRANGE,0,MAKELONG(9999,0));
+ SetDlgItemInt(hwndDlg, IDC_EDIT_HIDETIME, cfg_uioptions_appbarshidetime.getValueAsInt(), 0);
+
+ dock_dist = dock_dist2 = spin_inc = spin_show = spin_hide = 1;
+ return 1;
+ }
+ case WM_COMMAND:
+ toggle_from_wa2 = 1;
+ switch (LOWORD(wParam))
+ {
+ case IDC_CHECK_DESKTOPALPHA:
+ cfg_uioptions_desktopalpha.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_CHECK_DESKTOPALPHA));
+ return 0;
+ case IDC_BUTTON_AUTOTIMERRES:
+ autoTimerRes(hwndDlg);
+ return 0;
+ case IDC_CHECK_TOOLTIPS:
+ cfg_uioptions_tooltips.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_CHECK_TOOLTIPS));
+ return 0;
+ case IDC_CHECK_DOCKING:
+ cfg_options_docking.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_CHECK_DOCKING));
+ return 0;
+ case IDC_CHECK_DOCKING2:
+ cfg_options_appbarondrag.setValueAsInt(IsDlgButtonChecked(hwndDlg, IDC_CHECK_DOCKING2));
+ return 0;
+ case IDC_EDIT_DOCKDISTANCE:
+ if (HIWORD(wParam) == EN_CHANGE && dock_dist)
+ {
+ int t, a = GetDlgItemInt(hwndDlg, IDC_EDIT_DOCKDISTANCE, &t, 0);
+ if (t) cfg_options_dockingdistance.setValueAsInt(a);
+ }
+ return 0;
+ case IDC_EDIT_DOCKDISTANCE2:
+ if (HIWORD(wParam) == EN_CHANGE && dock_dist2)
+ {
+ int t, a = GetDlgItemInt(hwndDlg, IDC_EDIT_DOCKDISTANCE2, &t, 0);
+ if (t) cfg_options_appbardockingdistance.setValueAsInt(a);
+ }
+ return 0;
+ case IDC_EDIT_INCREMENT:
+ if (HIWORD(wParam) == EN_CHANGE && spin_inc)
+ {
+ int t, a = GetDlgItemInt(hwndDlg, IDC_EDIT_INCREMENT, &t, 0);
+ if (t) cfg_uioptions_textincrement.setValueAsInt(a);
+ }
+ return 0;
+ case IDC_EDIT_SHOWTIME:
+ if (HIWORD(wParam) == EN_CHANGE && spin_show)
+ {
+ int t, a = GetDlgItemInt(hwndDlg, IDC_EDIT_SHOWTIME, &t, 0);
+ if (t) cfg_uioptions_appbarsshowtime.setValueAsInt(a);
+ }
+ return 0;
+ case IDC_EDIT_HIDETIME:
+ if (HIWORD(wParam) == EN_CHANGE && spin_hide)
+ {
+ int t, a = GetDlgItemInt(hwndDlg, IDC_EDIT_HIDETIME, &t, 0);
+ if (t) cfg_uioptions_appbarshidetime.setValueAsInt(a);
+ }
+ return 0;
+ }
+ toggle_from_wa2 = 0;
+ break;
+ case WM_HSCROLL:
+ {
+ int t = (int)SendMessageW((HWND) lParam, TBM_GETPOS, 0, 0);
+ HWND ctrl = (HWND) lParam;
+ if (ctrl == GetDlgItem(hwndDlg, IDC_SLIDER_TIMERRESOLUTION))
+ {
+ cfg_uioptions_timerresolution.setValueAsInt(t);
+ SetDlgItemTextW(hwndDlg, IDC_STATIC_TIMERRES, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_TIMERS_RESOLUTION), cfg_uioptions_timerresolution.getValueAsInt()));
+ }
+ else if (ctrl == GetDlgItem(hwndDlg, IDC_SLIDER_TICKERSPEED))
+ {
+ cfg_uioptions_textspeed.setValueAsDouble(1.0 / (float)(t + 1));
+ SetDlgItemTextW(hwndDlg, IDC_STATIC_TICKER, StringPrintfW(WASABI_API_LNGSTRINGW(IDS_TEXT_SCROLL_SPEED), getScrollTextSpeedW((float)cfg_uioptions_textspeed.getValueAsDouble())));
+ }
+ break;
+ }
+ case WM_DESTROY:
+ subWnd = NULL;
+ dock_dist = dock_dist2 = spin_inc = spin_show = spin_hide = 0;
+ return 0;
+ }
+
+ const int controls[] =
+ {
+ IDC_SLIDER_TIMERRESOLUTION,
+ IDC_SLIDER_TICKERSPEED,
+ };
+ if (FALSE != WASABI_API_APP->DirectMouseWheel_ProcessDialogMessage(hwndDlg, uMsg, wParam, lParam, controls, ARRAYSIZE(controls)))
+ return TRUE;
+
+ return 0;
+}
diff --git a/Src/Plugins/General/gen_ff/resource.h b/Src/Plugins/General/gen_ff/resource.h
new file mode 100644
index 00000000..1f91ed89
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/resource.h
@@ -0,0 +1,261 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by gen_ff.rc
+//
+#define IDS_SEND_TO 1
+#define IDS_NO_THEME_AVAILABLE 2
+#define IDS_COLOR_THEMES 3
+#define IDS_CURRENT_SKIN 4
+#define IDS_NO_SKIN_LOADED 5
+#define IDS_MODERN_SKIN_SUPPORT_CLASSIC 6
+#define IDS_MODERN_SKIN_SUPPORT 7
+#define IDS_CUSTOM_X_PERCENT 8
+#define IDS_CUSTOM 9
+#define IDS_WINDOW_SETTINGS 10
+#define IDS_SCALE_X_PERCENT 11
+#define IDS_OPACITY_X_PERCENT 12
+#define IDS_GHK_SHOW_NOTIFICATION 13
+#define IDS_MODERN_SKINS 14
+#define IDS_GENERAL 15
+#define IDS_ALPHA_BLENDING 16
+#define IDS_FONT_RENDERING 17
+#define IDS_ERROR_WHILE_LOADING_SKIN_WINDOW 18
+#define IDS_NO_OPTIONS_AVAILABLE_FOR_THIS_SKIN 19
+#define IDS_AUTO_UNICODE_LATIN1_ASCII 20
+#define IDS_FONT 21
+#define IDS_MAPPING 22
+#define IDS_SCALE 23
+#define IDS_TYPE 24
+#define IDS_THIS_SKIN 25
+#define IDS_ALL_SKINS 26
+#define IDS_FASTER 27
+#define IDS_FAST 28
+#define IDS_AVERAGE 29
+#define IDS_SLOW 30
+#define IDS_SLOWER 31
+#define IDS_FAILED_TO_DETECT_OPTIMAL_RESOLUTION 32
+#define IDS_AUTO_DETECTING 33
+#define IDS_PREPARING_AUTO_DETECTION 34
+#define IDS_AUTO_DETECTION_SUCCESSFUL 35
+#define IDS_ACCEPT 36
+#define IDS_N_A 37
+#define IDS_TIMERS_RESOLUTION 38
+#define IDS_TEXT_SCROLL_SPEED 39
+#define IDS_CROSSFADER_ONLY_UNDER_OUT_DS 40
+#define IDS_NOT_SUPPORTED 41
+#define IDS_PLAYLIST_EDITOR 42
+#define IDS_VIDEO 43
+#define IDS_MONO 44
+#define IDS_STEREO 45
+#define IDS_X_CHANNELS 46
+#define IDS_BY_SPACE 47
+#define IDS_COULD_NOT_FIND_WINAMP 48
+#define IDS_ERROR 49
+#define IDS_WINAMP_NOT_FOUND 50
+#define IDS_VISUALIZATIONS 51
+#define IDS_STRING52 52
+#define IDS_MEDIA_LIBRARY 52
+#define IDS_NO_SET 53
+#define IDS_SLOT_X_X 54
+#define IDS_COLOR_EDITOR 55
+#define IDS_SKIN_SETTINGS 56
+#define IDS_WEB_BROWSER 57
+#define IDS_STRING58 58
+#define IDS_ALBUM_ART 58
+#define IDS_NO_VISUALISATION 59
+#define IDS_SPECTRUM_ANALYZER 60
+#define IDS_STRING61 61
+#define IDS_OSCILLOSCOPE 61
+#define IDS_SKIN_LOAD_FORMAT_OLD 62
+#define IDS_SKIN_LOAD_FORMAT_TOO_RECENT 63
+#define IDS_SKIN_LOAD_WARNING 64
+#define IDS_SKIN_LOAD_NOT_SUPPORTED 65
+#define IDS_NO_SKIN_LOADED_ 66
+#define IDS_XUITHEME_LOAD 67
+#define IDS_XUITHEME_SAVE 68
+#define IDS_MS 69
+#define IDS_KHZ 70
+#define IDS_STRING71 71
+#define IDS_KBPS 71
+#define IDS_USELOCK 72
+#define IDS_ALLLOCKED 73
+#define IDS_OPAQUE_FOCUS 74
+#define IDS_OPAQUE_HOVER 75
+#define IDS_NO_OPACITY 76
+#define IDS_LOADING 77
+#define IDB_PLEDIT_TAB_NORMAL 110
+#define IDB_PLEDIT_TAB_HILITED 111
+#define IDB_PLEDIT_TAB_SELECTED 112
+#define IDB_VIDEO_TAB_NORMAL 120
+#define IDB_VIDEO_TAB_HILITED 121
+#define IDB_VIDEO_TAB_SELECTED 122
+#define IDD_ABOUT 124
+#define IDR_SONGINFO 128
+#define IDB_MB_TAB_NORMAL 130
+#define IDB_MB_TAB_HILITED 131
+#define IDB_MB_TAB_SELECTED 132
+#define IDB_ML_TAB_NORMAL 133
+#define IDD_DIALOG1 133
+#define IDB_ML_TAB_HILITED 134
+#define IDD_FONTMAPPER 134
+#define IDB_ML_TAB_SELECTED 135
+#define IDB_VIS_TAB_NORMAL 136
+#define IDB_VIS_TAB_HILITED 137
+#define IDB_VIS_TAB_SELECTED 138
+#define IDD_MEDIA_DOWNLOADER 141
+#define IDD_PREFS_WINDOWS 142
+#define IDC_CHECK_DESKTOPALPHA 1002
+#define IDC_STATIC_DA1 1003
+#define IDC_STATIC_DA3 1005
+#define IDC_TAB1 1006
+#define IDC_LIST1 1007
+#define IDC_BUTTON_SETTHEME 1008
+#define IDC_VERSTR 1009
+#define IDC_CHECK_LINKALPHA 1011
+#define IDC_CHECK_LINKRATIO 1012
+#define IDC_SLIDER_TIMERRESOLUTION 1013
+#define IDC_STATIC_TIMERRES 1014
+#define IDC_CHECK_TOOLTIPS 1015
+#define IDC_CHECK_DOCKING 1016
+#define IDC_EDIT_DOCKDISTANCE 1017
+#define IDC_BUTTON_SKINSPECIFIC 1018
+#define IDC_CHECK_DOCKING2 1018
+#define IDC_SLIDER_TICKERSPEED 1019
+#define IDC_STATIC_TICKER 1020
+#define IDC_BUTTON_AUTOTIMERRES 1021
+#define IDC_EDIT_DOCKDISTANCE2 1022
+#define IDC_TXT 1023
+#define IDC_EDIT_INCREMENT 1023
+#define IDC_SLIDER_CUSTOMSCALE 1025
+#define IDC_STATIC_SCALE 1026
+#define IDC_EDIT_SHOWTIME 1027
+#define IDC_EDIT_HIDETIME 1028
+#define IDC_RECT 1186
+#define IDR_CONTROLMENU 1281
+#define IDD_PREFS_THEMES 1282
+#define IDC_CHECK_ALLOWBITMAPFONTS 1283
+#define IDD_PREFS 1284
+#define IDC_CHECK_ALTFONTS 1284
+#define IDD_AUTOTIMERRES 1285
+#define IDD_CUSTOMSCALE 1286
+#define IDC_COMBO_TTFOVERRIDE 1286
+#define IDD_PREFS_FONTS 1287
+#define IDC_STATIC_TTFOVERRIDE 1287
+#define IDC_SLIDER_SCALETTFOVERRIDE 1288
+#define IDC_STATIC_TTFSCALE 1289
+#define IDD_CUSTOMALPHA 1289
+#define IDC_CHECK_FREETYPETTF 1290
+#define IDD_PREFS_SKIN 1290
+#define IDC_COMBO_CHARMAP 1291
+#define IDC_STATIC_FREETYPE 1292
+#define IDC_STATIC_DECREASESIZE 1293
+#define IDC_STATIC_INCREASESIZE 1294
+#define IDC_NO_7BIT_OVERRIDE 1295
+#define IDC_CHECK_NO_ALT_7BIT_OVERRIDE 1296
+#define IDC_STATIC_CHARMAP 1297
+#define IDC_STATIC_ALTFONTS 1298
+#define IDC_COMBO_DEFAULTFONT 1299
+#define IDC_SLIDER_SCALEDEFAULTFONT 1300
+#define IDC_CHECK_LINKALLALPHA 1301
+#define IDC_STATIC_DECREASESIZE2 1301
+#define IDC_CHECK_LINKALLRATIO 1302
+#define IDC_STATIC_SCALEDEFAULTFONT 1302
+#define IDC_STATIC_INCREASESIZE2 1303
+#define IDC_STATIC_SCALEDEFAULTFONT2 1305
+#define IDC_RADIO_USELOCK 1306
+#define IDC_RADIO_ALLLOCKED 1307
+#define IDC_SLIDER_CUSTOMALPHA 1309
+#define IDC_STATIC_ALPHA 1311
+#define IDC_SLIDER_HOLD 1313
+#define IDC_STATIC_TRANSP 1314
+#define IDC_STATIC_OPAQUE 1315
+#define IDC_SLIDER_FADEIN 1316
+#define IDC_SLIDER_FADEOUT 1317
+#define IDC_STATIC_SCALE11 1318
+#define IDC_STATIC_HOLD 1319
+#define IDC_STATIC_FADEIN 1320
+#define IDC_STATIC_FADEOUT 1321
+#define IDC_STATIC_SCALE301 1322
+#define IDC_EDIT_EXTEND 1323
+#define IDC_STATIC_EXTEND 1324
+#define IDC_STATIC_GROUP 1326
+#define IDC_CHECK_USEFONTMAPPER 1330
+#define IDC_BUTTON_FONTMAPPER 1331
+#define IDC_LIST_MAPPINGS 1332
+#define IDC_RADIO_THISSKIN 1333
+#define IDC_RADIO_ALLSKINS 1334
+#define IDC_BUTTON_NEW 1335
+#define IDC_BUTTON_DEL 1336
+#define IDC_COMBO_SKINFONTS 1337
+#define IDC_COMBO_FONTS 1338
+#define IDC_SLIDER_SCALE 1339
+#define IDC_BUTTON_SET 1340
+#define IDC_STATIC_EMPTY 1344
+#define IDC_STATIC_OPACITY 1345
+#define IDC_STATIC_AUTOON 1346
+#define IDC_STATIC_AUTOONTXT 1347
+#define IDC_STATIC_FADEIN2 1348
+#define IDC_STATIC_FADEOUT2 1349
+#define IDC_STATIC_HOLD2 1350
+#define IDC_STATIC_EXTENDBOX 1351
+#define IDC_URL 1352
+#define IDC_PROGRESS 1353
+#define IDC_DOWNLOADTO 1354
+#define IDC_SPIN_EXTEND 1356
+#define IDC_SPIN_DOCKDISTANCE 1357
+#define IDC_SPIN_DOCKDISTANCE2 1358
+#define IDC_COMBO_SCALE 1358
+#define IDC_SPIN_INCREMENT 1359
+#define IDC_COMBO_OPACITY 1359
+#define IDC_SPIN_SHOWTIME 1360
+#define IDC_SPIN_HIDETIME 1361
+#define IDD_PREFS_GENERAL 1362
+#define WINAMP_EDIT_ID3 40188
+#define WINAMP_JUMP 40193
+#define WINAMP_JUMPFILE 40194
+#define ID_CONTROLMENU_OPACITY_10 42202
+#define ID_CONTROLMENU_OPACITY_20 42203
+#define ID_CONTROLMENU_OPACITY_30 42204
+#define ID_CONTROLMENU_OPACITY_40 42205
+#define ID_CONTROLMENU_OPACITY_50 42206
+#define ID_CONTROLMENU_OPACITY_60 42207
+#define ID_CONTROLMENU_OPACITY_70 42208
+#define ID_CONTROLMENU_OPACITY_80 42209
+#define ID_CONTROLMENU_OPACITY_90 42210
+#define ID_CONTROLMENU_OPACITY_100 42211
+#define ID_CONTROLMENU_SCALING_25 42213
+#define ID_CONTROLMENU_SCALING_50 42214
+#define ID_CONTROLMENU_SCALING_75 42215
+#define ID_CONTROLMENU_SCALING_100 42216
+#define ID_CONTROLMENU_SCALING_200 42217
+#define ID_CONTROLMENU_SCALING_250 42218
+#define ID_CONTROLMENU_SCALING_300 42219
+#define ID_CONTROLMENU_SCALING_150 42222
+#define ID_CONTROLMENU_SCALING_LOCKED 42223
+#define ID_CONTROLMENU_SCALING_CUSTOM 42224
+#define ID_CONTROLMENU_SCALING_FOLLOWDOUBLESIZE 42225
+#define ID_CONTROLMENU_OPACITY_AUTO100 42226
+#define ID_CONTROLMENU_OPACITY_AUTO100_HOVER 42226
+#define ID_CONTROLMENU_OPACITY_CUSTOM 42227
+#define ID_CONTROLMENU_OPACITY_AUTO100_FOCUS 42228
+#define ID_CONTROLMENU_TOOLBAR_TOP 42229
+#define ID_CONTROLMENU_TOOLBAR_RIGHT 42231
+#define ID_CONTROLMENU_TOOLBAR_BOTTOM 42232
+#define ID_CONTROLMENU_TOOLBAR_DISABLED 42233
+#define ID_CONTROLMENU_TOOLBAR_ALWAYSONTOP 42234
+#define ID_CONTROLMENU_TOOLBAR_AUTOHIDE 42235
+#define ID_CONTROLMENU_TOOLBAR_LEFT 42236
+#define ID_CONTROLMENU_TOOLBAR_AUTODOCKONDRAG 42237
+#define ID_CONTROLMENU_SCALING_125 42238
+#define IDS_NULLSOFT_MODERN_SKINS 65534
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 143
+#define _APS_NEXT_COMMAND_VALUE 42238
+#define _APS_NEXT_CONTROL_VALUE 1359
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/General/gen_ff/servicelink.cpp b/Src/Plugins/General/gen_ff/servicelink.cpp
new file mode 100644
index 00000000..f7b17444
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/servicelink.cpp
@@ -0,0 +1,72 @@
+#include <precomp.h>
+
+// these are pragmas to force a reference to objects that otherwise are entirely decoupled from the rest of the
+// program except for their static constructor code -- in this case, if the code is in a lib, the object gets
+// optimized out, and we definitly do not want that
+//
+// generally you want to add more of these pragmas for services declared through the BEGIN_SERVICES/END_SERVICES
+// macros which you want to link with
+
+// color themes list xui object
+#ifdef WASABI_COMPILE_COLORTHEMES
+#pragma comment(linker, "/include:__link_ColorThemesListXuiSvc")
+#endif
+
+// config script objects
+#ifdef WASABI_COMPILE_CONFIG
+#pragma comment(linker, "/include:__link_ConfigObjectSvc")
+#endif
+
+// minibrowser service
+#ifdef WASABI_WIDGETS_BROWSER
+#pragma comment(linker, "/include:__link_MbSvc")
+#endif
+
+// skinned tooltips
+#ifdef WASABI_WIDGETS_TOOLTIPS
+#pragma comment(linker, "/include:__link_GroupTipsSvc")
+#endif
+
+// freetype font renderer
+#ifdef WASABI_FONT_RENDERER_USE_FREETYPE
+//#pragma comment(linker, "/include:__link_FreeTypeFontRenderer_Svc")
+#endif
+
+// pldir svc
+#pragma comment(linker, "/include:__link_wa2PlDirObj_Svcs")
+
+// pleditor xuiobject
+#pragma comment(linker, "/include:__link_Wa2PleditXuiSvc")
+
+// song ticker xui object
+#pragma comment(linker, "/include:__link_wa2SongTicker_Svcs")
+
+// Winamp Config script object
+#pragma comment(linker, "/include:__link_WinampConfig_svcs")
+
+// progress grid xui object
+#ifdef WASABI_WIDGETS_MEDIASLIDERS
+#pragma comment(linker, "/include:__link_ProgressGridXuiSvc")
+#endif
+
+// gradient xui object
+#ifdef WASABI_WIDGETS_MEDIASLIDERS
+#pragma comment(linker, "/include:__link_GradientXuiSvc")
+#endif
+
+#pragma comment(linker, "/include:__link_GroupXFadeXuiSvc")
+
+#pragma comment(linker, "/include:__link_GradientGen_Svc")
+
+#pragma comment(linker, "/include:__link_OsEdgeGen_Svc")
+
+#pragma comment(linker, "/include:__link_PolyGen_Svc")
+
+#pragma comment(linker, "/include:__link_SolidGen_Svc")
+
+#pragma comment(linker, "/include:__link_ScriptCore_Svc")
+
+
+
+//#pragma comment(linker, "/include:__link_ColorEditor_Svc")
+
diff --git a/Src/Plugins/General/gen_ff/skininfo.cpp b/Src/Plugins/General/gen_ff/skininfo.cpp
new file mode 100644
index 00000000..520bd767
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/skininfo.cpp
@@ -0,0 +1,141 @@
+#include <precomp.h>
+#include "skininfo.h"
+#include "../xml/obj_xml.h"
+#include <api/xml/XMLAutoInclude.h>
+#include <api/xml/LoadXML.h>
+#include "../nu/AutoChar.h"
+#include "gen.h"
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+SkinInfosXmlReader::SkinInfosXmlReader(const wchar_t *skinname) : SkinInfoBlock(skinname)
+{
+ waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (parserFactory)
+ {
+ obj_xml *parser = (obj_xml *)parserFactory->getInterface();
+ if (parser)
+ {
+ {
+ StringPathCombine skinPath(WASABI_API_SKIN->getSkinsPath(), skinname);
+
+ XMLAutoInclude include(parser, skinPath);
+ parser->xmlreader_registerCallback(L"WinampAbstractionLayer",this);
+ //parser->xmlreader_registerCallback(L"WinampAbstractionLayer\fSkinInfo", this);
+ parser->xmlreader_registerCallback(L"WinampAbstractionLayer\fSkinInfo\f*", this);
+ parser->xmlreader_registerCallback(L"WasabiXML",this);
+ //parser->xmlreader_registerCallback(L"WasabiXML\fSkinInfo", this);
+ parser->xmlreader_registerCallback(L"WasabiXML\fSkinInfo\f*", this);
+ parser->xmlreader_open();
+
+ skinPath.AppendPath(L"skin.xml");
+ LoadXmlFile(parser, skinPath);
+ parser->xmlreader_unregisterCallback(this);
+ }
+ parser->xmlreader_close();
+ parserFactory->releaseInterface(parser);
+ parser = 0;
+ }
+ }
+}
+
+void SkinInfosXmlReader::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ if (!_wcsicmp(xmltag, L"WinampAbstractionLayer") || !_wcsicmp(xmltag, L"WasabiXML"))
+ {
+ const wchar_t *version = params->getItemValue(L"version");
+ if (version)
+ walversion = version;
+ }
+}
+
+void SkinInfosXmlReader::xmlReaderOnCharacterDataCallback(const wchar_t *xmlpath, const wchar_t *xmltag, const wchar_t *s)
+{
+ if (!wcscmp(xmltag, L"name")) { fullname = s;}
+ else if (!wcscmp(xmltag, L"version")) { version = s;}
+ else if (!wcscmp(xmltag, L"comment")) { comment = s;}
+ else if (!wcscmp(xmltag, L"author")) { author = s;}
+ else if (!wcscmp(xmltag, L"email")) { email = s;}
+ else if (!wcscmp(xmltag, L"homepage")) { homepage = s;}
+ else if (!wcscmp(xmltag, L"parentskin")) { parentskin = s;}
+ else if (!wcscmp(xmltag, L"screenshot")) { screenshot = s;}
+}
+
+extern int m_are_we_loaded;
+static StringW skin;
+
+const wchar_t *getSkinInfoW()
+{
+ static StringW skininfoW;
+
+ // these checks is repeated in getSkinInfo, also
+ if (!m_are_we_loaded) return NULL;
+ if (skin.iscaseequal(WASABI_API_SKIN->getSkinName()) && !skininfoW.isempty()) return skininfoW;
+
+ skininfoW = L"";
+ SkinInfosXmlReader r(WASABI_API_SKIN->getSkinName());
+
+ /* skin name */
+ const wchar_t *name = r.getFullName();
+ if (name && *name)
+ skininfoW += name;
+ else
+ skininfoW += WASABI_API_SKIN->getSkinName();
+
+ /* skin version */
+ const wchar_t *ver = r.getVersion();
+ if (ver && *ver)
+ {
+ skininfoW += L" v";
+ skininfoW += ver;
+ }
+ skininfoW += L"\r\n";
+
+ /* skin author & e-mail */
+ const wchar_t *aut = r.getAuthor();
+ if (aut && *aut)
+ {
+ skininfoW += WASABI_API_LNGSTRINGW(IDS_BY_SPACE);
+ skininfoW += aut;
+
+ const wchar_t *email = r.getEmail();
+ if (email && *email)
+ {
+ skininfoW += L" (";
+ skininfoW += email;
+ skininfoW += L")";
+ }
+ skininfoW += L"\r\n";
+ }
+
+ /* skin homepage */
+ const wchar_t *web = r.getHomepage();
+ if (web && *web)
+ {
+ skininfoW += web;
+ skininfoW += L"\r\n";
+ }
+ skininfoW += L"\r\n";
+ const wchar_t *comment = r.getComment();
+ if (comment && *comment)
+ skininfoW += comment;
+
+ skin = WASABI_API_SKIN->getSkinName();
+ return skininfoW;
+}
+
+const char *getSkinInfo()
+{
+ static String skininfo;
+
+ // these checks is repeated in getSkinInfoW, also
+ if (!m_are_we_loaded) return NULL;
+ if (skin.iscaseequal(WASABI_API_SKIN->getSkinName()) && !skininfo.isempty()) return skininfo;
+
+ // get the wide character version
+ const wchar_t *wideSkinInfo = getSkinInfoW();
+
+ // and convert
+ skininfo = AutoChar(wideSkinInfo);
+ return skininfo;
+} \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/skininfo.h b/Src/Plugins/General/gen_ff/skininfo.h
new file mode 100644
index 00000000..33d77553
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/skininfo.h
@@ -0,0 +1,42 @@
+#ifndef _SKININFO_H
+#define _SKININFO_H
+
+#include "../xml/obj_xml.h"
+#include "../xml/ifc_xmlreadercallbacki.h"
+#include <bfc/string/StringW.h>
+
+class SkinInfoBlock {
+public:
+ SkinInfoBlock(const wchar_t *name) : name(name),fullname(name) { }
+ const wchar_t *getName() { return name; }
+ const wchar_t *getParentSkin() { return parentskin; }
+ const wchar_t *getFullName() { return fullname; }
+ const wchar_t *getVersion() { return version; }
+ const wchar_t *getComment() { return comment; }
+ const wchar_t *getAuthor() { return author; }
+ const wchar_t *getEmail() { return email; }
+ const wchar_t *getHomepage() { return homepage; }
+ const wchar_t *getScreenshot() { return screenshot; }
+protected:
+ StringW name;
+ StringW walversion;
+ StringW parentskin;
+
+ StringW fullname;
+ StringW version;
+ StringW comment;
+ StringW author;
+ StringW email;
+ StringW homepage;
+ StringW screenshot;
+};
+
+class SkinInfosXmlReader : public SkinInfoBlock, public ifc_xmlreadercallbackI
+{
+public:
+ SkinInfosXmlReader(const wchar_t *skinname);
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ void xmlReaderOnCharacterDataCallback(const wchar_t *xmlpath, const wchar_t *xmltag, const wchar_t *s);
+};
+
+#endif
diff --git a/Src/Plugins/General/gen_ff/wa2buckitems.cpp b/Src/Plugins/General/gen_ff/wa2buckitems.cpp
new file mode 100644
index 00000000..0fb57bba
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2buckitems.cpp
@@ -0,0 +1,96 @@
+#include <precomp.h>
+#include "wa2buckitems.h"
+#include "wa2frontend.h"
+#include "wa2wndembed.h"
+#include "gen.h"
+#include "../Agave/Language/api_language.h"
+
+
+//-------------------------------------------------------------------------------------------
+Wa2BucketItem::Wa2BucketItem(GUID g, const wchar_t *t) : BucketItemT<ButtonWnd> (g, t) {
+}
+
+Wa2BucketItem::~Wa2BucketItem() {
+}
+
+//-------------------------------------------------------------------------------------------
+
+PlBucketItem::PlBucketItem() : Wa2BucketItem(INVALID_GUID, L"Playlist Editor") {
+}
+
+PlBucketItem::~PlBucketItem() {
+}
+
+void PlBucketItem::onLeftPush(int x, int y) {
+ BUCKETITEM_PARENT::onLeftPush(x, y);
+ wa2.setWindowVisible(IPC_GETWND_PE, !wa2.isWindowVisible(IPC_GETWND_PE));
+}
+
+
+//-------------------------------------------------------------------------------------------
+EmbedBucketItem::EmbedBucketItem() : Wa2BucketItem(INVALID_GUID, L"Embed?") {
+}
+
+EmbedBucketItem::~EmbedBucketItem() {
+}
+
+void EmbedBucketItem::onLeftPush(int x, int y) {
+ BUCKETITEM_PARENT::onLeftPush(x, y);
+ //wa2.setWindowVisible(IPC_GETWND_PE, !wa2.isWindowVisible(IPC_GETWND_PE));
+}
+
+//-------------------------------------------------------------------------------------------
+#ifdef MINIBROWSER_SUPPORT
+
+MbBucketItem::MbBucketItem() : Wa2BucketItem(INVALID_GUID, L"Minibrowser") {
+}
+
+MbBucketItem::~MbBucketItem() {
+}
+
+void MbBucketItem::onLeftPush(int x, int y) {
+ BUCKETITEM_PARENT::onLeftPush(x, y);
+ wa2.setWindowVisible(IPC_GETWND_MB, !wa2.isWindowVisible(IPC_GETWND_MB));
+}
+#endif
+
+//-------------------------------------------------------------------------------------------
+VidBucketItem::VidBucketItem() : Wa2BucketItem(INVALID_GUID, L"Video Window") {
+}
+
+VidBucketItem::~VidBucketItem() {
+}
+
+//-------------------------------------------------------------------------------------------
+void VidBucketItem::onLeftPush(int x, int y) {
+ BUCKETITEM_PARENT::onLeftPush(x, y);
+ wa2.setWindowVisible(IPC_GETWND_VIDEO, !wa2.isWindowVisible(IPC_GETWND_VIDEO));
+}
+
+//-------------------------------------------------------------------------------------------
+
+MlBucketItem::MlBucketItem() : Wa2BucketItem(INVALID_GUID, L"Winamp Library") {
+}
+
+MlBucketItem::~MlBucketItem() {
+}
+
+#define WA_MEDIALIB_MENUITEM_ID 23123
+
+void MlBucketItem::onLeftPush(int x, int y) {
+ BUCKETITEM_PARENT::onLeftPush(x, y);
+ SendMessageW(wa2.getMainWindow(), WM_COMMAND, WA_MEDIALIB_MENUITEM_ID, 0);
+}
+
+//-------------------------------------------------------------------------------------------
+
+VisBucketItem::VisBucketItem() : Wa2BucketItem(INVALID_GUID, L"Visualizations") {
+}
+
+VisBucketItem::~VisBucketItem() {
+}
+
+void VisBucketItem::onLeftPush(int x, int y) {
+ BUCKETITEM_PARENT::onLeftPush(x, y);
+ wa2.toggleVis();
+} \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/wa2buckitems.h b/Src/Plugins/General/gen_ff/wa2buckitems.h
new file mode 100644
index 00000000..2238aa49
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2buckitems.h
@@ -0,0 +1,70 @@
+#ifndef __WA2BUCKETITEMS_H
+#define __WA2BUCKETITEMS_H
+
+#include <api/wnd/bucketitem.h>
+
+#define WA2BUCKETITEM_PARENT Wa2BucketItem
+
+//-------------------------------------------------------------------------------------------
+class Wa2BucketItem : public BucketItemT<ButtonWnd> {
+ public:
+ Wa2BucketItem(GUID g=INVALID_GUID, const wchar_t *text=NULL);
+ virtual ~Wa2BucketItem();
+};
+
+//-------------------------------------------------------------------------------------------
+class PlBucketItem : public Wa2BucketItem {
+ public:
+ PlBucketItem();
+ virtual ~PlBucketItem();
+ void onLeftPush(int x, int y);
+};
+
+//-------------------------------------------------------------------------------------------
+class EmbedBucketItem : public Wa2BucketItem {
+ public:
+ EmbedBucketItem();
+ virtual ~EmbedBucketItem();
+ void onLeftPush(int x, int y);
+};
+
+#ifdef MINIBROWSER_SUPPORT
+
+//-------------------------------------------------------------------------------------------
+class MbBucketItem : public Wa2BucketItem {
+ public:
+ MbBucketItem();
+ virtual ~MbBucketItem();
+ void onLeftPush(int x, int y);
+};
+
+#endif
+
+//-------------------------------------------------------------------------------------------
+class VidBucketItem : public Wa2BucketItem {
+ public:
+ VidBucketItem();
+ virtual ~VidBucketItem();
+ void onLeftPush(int x, int y);
+};
+
+//-------------------------------------------------------------------------------------------
+class VisBucketItem : public Wa2BucketItem {
+ public:
+ VisBucketItem();
+ virtual ~VisBucketItem();
+ void onLeftPush(int x, int y);
+};
+
+//-------------------------------------------------------------------------------------------
+class MlBucketItem : public Wa2BucketItem {
+ public:
+ MlBucketItem();
+ virtual ~MlBucketItem();
+ void onLeftPush(int x, int y);
+};
+
+
+
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/wa2cfgitems.cpp b/Src/Plugins/General/gen_ff/wa2cfgitems.cpp
new file mode 100644
index 00000000..a225df8c
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2cfgitems.cpp
@@ -0,0 +1,306 @@
+#include <precomp.h>
+#include "wa2cfgitems.h"
+#include "wa2wndembed.h"
+#include "wa2core.h"
+#include <api/config/options.h>
+#include "wa2frontend.h"
+#include "../../Plugins/Output/out_ds/ds_ipc.h"
+#include <bfc/parse/pathparse.h>
+#include "gen.h"
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+
+// cfg item callbacks
+void setCrossfader(int crossfade);
+void onWa2CrossfadeChange(int crossfade);
+void setOnTop(int ontop);
+void onWa2OnTopChanged(int ontop);
+
+int my_set = 0;
+int disable_set_wa2_repeat = 0;
+
+//---------------------------------------------------------
+// playlist editor cfg items
+//---------------------------------------------------------
+_bool shuffle(L"Shuffle", FALSE);
+_int repeat(L"Repeat", 0);
+_bool visrandom(L"Random", FALSE);
+
+Wa2PlEditCfgItems::Wa2PlEditCfgItems() : CfgItemI(L"Playlist Editor", pleditWndGuid) {
+ registerAttribute(&shuffle, new int_attrCB(Wa2PlEditCfgItems::onSetShuffle));
+ registerAttribute(&repeat, new int_attrCB(Wa2PlEditCfgItems::onSetRepeat));
+ WASABI_API_CONFIG->config_registerCfgItem(this);
+ shuffle.setValueAsInt(g_Core->getShuffle());
+ disable_set_wa2_repeat = 1;
+ repeat.setValueAsInt(g_Core->getRepeat());
+ disable_set_wa2_repeat = 0;
+}
+
+Wa2PlEditCfgItems::~Wa2PlEditCfgItems() {
+ WASABI_API_CONFIG->config_deregisterCfgItem(this);
+}
+
+void Wa2PlEditCfgItems::onSetRepeat(int set) {
+ my_set = 1;
+ ASSERT(g_Core != NULL);
+ if (!disable_set_wa2_repeat) {
+ // if (!!set != !!g_Core->getRepeat()) // FG> do NOT uncomment this
+ g_Core->setRepeat(set);
+ }
+ my_set = 0;
+}
+
+void Wa2PlEditCfgItems::onSetShuffle(BOOL set) {
+ my_set = 1;
+ ASSERT(g_Core != NULL);
+ if (!!set != !!g_Core->getShuffle())
+ g_Core->setShuffle(set);
+ my_set = 0;
+}
+
+//---------------------------------------------------------
+static _bool prevent_videostoponclose(L"Prevent video playback Stop on video window Close", FALSE);
+static _bool prevent_videoresize(L"Prevent video resize", FALSE); // 5.32+
+static _bool show_videownd_on_play(L"Show video wnd on play"); // 5.36+
+static _bool hide_videownd_on_stop(L"Hide video wnd on stop"); // 5.36+
+int preventvc_savedvalued = -1;
+int preventvresize_savedvalued = -1;
+
+SkinTweaks::SkinTweaks() : CfgItemI(L"SkinTweaks", skinTweaksGuid)
+{
+ registerAttribute(&prevent_videostoponclose, new int_attrCB(SkinTweaks::onPreventVideoStopChanged));
+ registerAttribute(&prevent_videoresize, new int_attrCB(SkinTweaks::onPreventVideoResize));
+}
+
+//---------------------------------------------------------
+AvsCfg::AvsCfg() : CfgItemI(L"Avs", avs_guid) {
+ registerAttribute(&visrandom, new int_attrCB(AvsCfg::onVisRandomChanged));
+}
+
+//---------------------------------------------------------
+void SkinTweaks::onPreventVideoStopChanged(BOOL set) {
+ if (set) {
+ if (preventvc_savedvalued == -1) {
+ preventvc_savedvalued = wa2.getStopOnVideoClose();
+ wa2.setStopOnVideoClose(0);
+ }
+ } else {
+ if (preventvc_savedvalued != -1) {
+ wa2.setStopOnVideoClose(preventvc_savedvalued);
+ preventvc_savedvalued = -1;
+ }
+ }
+}
+
+void SkinTweaks::onPreventVideoResize(BOOL set) {
+ if (set) {
+ if (preventvresize_savedvalued == -1) {
+ preventvresize_savedvalued = wa2.GetVideoResize();
+ wa2.SetVideoResize(0);
+ }
+ } else {
+ if (preventvresize_savedvalued != -1) {
+ wa2.SetVideoResize(preventvresize_savedvalued);
+ preventvresize_savedvalued = -1;
+ }
+ }
+}
+
+
+//---------------------------------------------------------
+void AvsCfg::onVisRandomChanged(BOOL set) {
+ extern int disable_send_visrandom;
+ if (!disable_send_visrandom) {
+ disable_send_visrandom = 1;
+ wa2.visRandom(set);
+ disable_send_visrandom = 0;
+ }
+}
+
+//---------------------------------------------------------
+Options *options;
+CustomOptionsMenuItems *optionsmenuitems;
+CustomWindowsMenuItems *windowsmenuitems;
+SkinTweaks *skintweaks;
+Crossfader *crossfader;
+AvsCfg *avscfg;
+//---------------------------------------------------------
+
+Wa2CfgItems::Wa2CfgItems() {
+ // set up main options
+ WASABI_API_CONFIG->config_registerCfgItem((options = new Options()));
+
+ // set up custom options menu items
+ WASABI_API_CONFIG->config_registerCfgItem((optionsmenuitems = new CustomOptionsMenuItems()));
+
+ // set up custom windows menu items
+ WASABI_API_CONFIG->config_registerCfgItem((windowsmenuitems = new CustomWindowsMenuItems()));
+
+ // set up skintweaks options menu items
+ WASABI_API_CONFIG->config_registerCfgItem((skintweaks = new SkinTweaks()));
+
+ // set up crossfader options menu item
+ WASABI_API_CONFIG->config_registerCfgItem((crossfader = new Crossfader()));
+
+ // set up avs cfg item
+ WASABI_API_CONFIG->config_registerCfgItem((avscfg = new AvsCfg()));
+}
+
+Wa2CfgItems::~Wa2CfgItems() {
+ WASABI_API_CONFIG->config_deregisterCfgItem(options);
+ WASABI_API_CONFIG->config_deregisterCfgItem(optionsmenuitems);
+ WASABI_API_CONFIG->config_deregisterCfgItem(windowsmenuitems);
+ WASABI_API_CONFIG->config_deregisterCfgItem(skintweaks);
+ WASABI_API_CONFIG->config_deregisterCfgItem(crossfader);
+ WASABI_API_CONFIG->config_deregisterCfgItem(avscfg);
+ delete options;
+ options = NULL;
+ delete optionsmenuitems;
+ optionsmenuitems = NULL;
+ delete windowsmenuitems;
+ windowsmenuitems = NULL;
+ delete skintweaks;
+ skintweaks = NULL;
+ delete crossfader;
+ crossfader = NULL;
+ delete avscfg;
+ avscfg = NULL;
+}
+
+//-----------------------------------------------------------------------------------------------
+// always on top was toggled in freeform skin
+//-----------------------------------------------------------------------------------------------
+void setOnTop(int ontop) {
+ if (!!ontop != !!wa2.isOnTop()) wa2.setOnTop(!!ontop);
+}
+
+//-----------------------------------------------------------------------------------------------
+// setontop was toggled in wa2
+//-----------------------------------------------------------------------------------------------
+void onWa2OnTopChanged(int ontop) {
+ cfg_options_alwaysontop.setValueAsInt(!!ontop);
+}
+
+//-----------------------------------------------------------------------------------------------
+// Crossfader cfgitem - monitors out_ds
+//-----------------------------------------------------------------------------------------------
+_int crossfade_time(L"Crossfade time", 2); // in seconds
+
+HWND output_ipc = NULL;
+static WNDPROC oldOutputIPCProc;
+int syncing_crossfade = 0;
+int using_dsound = 0;
+extern HWND last_dlg_parent;
+
+// sync out_ds with gen_ff
+void syncOutputCrossfade() {
+ if (output_ipc == NULL) return;
+ SendMessageW(output_ipc, WM_DS_IPC, crossfade_time.getValueAsInt() * 1000, DS_IPC_SET_CROSSFADE_TIME);
+ if (using_dsound) SendMessageW(output_ipc, WM_DS_IPC, cfg_audiooptions_crossfader.getValueAsInt(), DS_IPC_SET_CROSSFADE);
+}
+
+// sync gen_ff with out_ds, can't happen if out_ds isn't the selected plugin since this occurs when the user changes his config, and he needs to select out_ds to access its config
+void syncGenFFCrossfade() {
+ syncing_crossfade = 1;
+ if (output_ipc == NULL) return;
+ crossfade_time.setValueAsInt(SendMessageW(output_ipc, WM_DS_IPC, 0, DS_IPC_GET_CROSSFADE_TIME) / 1000);
+ cfg_audiooptions_crossfader.setValueAsInt(SendMessageW(output_ipc, WM_DS_IPC, 0, DS_IPC_GET_CROSSFADE));
+ syncing_crossfade = 0;
+}
+
+// called when gen_ff changes the crossfade time setting
+void onSetCrossfadeTime(int sectime) {
+ if (syncing_crossfade) return;
+ syncOutputCrossfade();
+}
+
+// called when gen_ff toggles crossfading
+void setCrossfader(int crossfade) {
+ if (syncing_crossfade) return;
+ if (crossfade && (!output_ipc || !using_dsound)) {
+ cfg_audiooptions_crossfader.setValueAsInt(0);
+ char title[256] = {0};
+ int r = MessageBoxA(last_dlg_parent ? last_dlg_parent : wa2.getMainWindow(),
+ WASABI_API_LNGSTRING(IDS_CROSSFADER_ONLY_UNDER_OUT_DS),
+ WASABI_API_LNGSTRING_BUF(IDS_NOT_SUPPORTED,title,256), MB_YESNO);
+ if (r == IDYES) {
+ SendMessageW(wa2.getMainWindow(),WM_WA_IPC,32,IPC_OPENPREFSTOPAGE);
+ }
+ }
+ syncOutputCrossfade();
+}
+
+// ----------------------- ipc hook
+extern int m_are_we_loaded;
+
+static DWORD WINAPI outputIPCProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam) {
+ if (m_are_we_loaded) {
+ switch (uMsg) {
+ case WM_DS_IPC:
+ switch (lParam) {
+ case DS_IPC_CB_CFGREFRESH:
+ syncGenFFCrossfade();
+ break;
+ case DS_IPC_CB_ONSHUTDOWN:
+ output_ipc = NULL;
+ break;
+ }
+ break;
+ }
+ }
+ return CallWindowProc(oldOutputIPCProc, hwndDlg, uMsg, wParam, lParam);
+}
+
+void hookOutputIPC() {
+ oldOutputIPCProc = (WNDPROC)SetWindowLongPtrW(output_ipc, GWLP_WNDPROC, (LONG_PTR)outputIPCProc);
+}
+
+// not called in fact, since we never need to let go of it
+void unhookOutputIPC() {
+ SetWindowLongPtrW(output_ipc, GWLP_WNDPROC, (LONG_PTR)oldOutputIPCProc);
+}
+
+BOOL CALLBACK findOutputIPCProc( HWND hwnd, LPARAM lParam )
+{
+ char cn[ 256 ] = { 0 };
+ GetClassNameA( hwnd, cn, 255 ); cn[ 255 ] = 0; // Must stay in ANSI mode
+ if ( STRCASEEQL( cn, DS_IPC_CLASSNAME ) )
+ {
+ output_ipc = hwnd;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+// ------------------------- output plugin changed !
+
+void Crossfader::onOutputChanged() {
+ if (!(output_ipc && IsWindow(output_ipc))) {
+ output_ipc = NULL;
+ EnumChildWindows(wa2.getMainWindow(), findOutputIPCProc, 0);
+
+ if (output_ipc) {
+ hookOutputIPC();
+ }
+ }
+
+ const char* outputPluginPath = wa2.getOutputPlugin();
+ PathParser pp(outputPluginPath);
+ using_dsound = STRCASEEQLSAFE(pp.getLastString(), "out_ds.dll");
+ if (!using_dsound) {
+ cfg_audiooptions_crossfader.setValueAsInt(0);
+ } else
+ syncGenFFCrossfade();
+}
+
+// ------------------------------------------------------------------------
+
+Crossfader::Crossfader() : CfgItemI(L"Crossfader", crossfaderGuid) {
+ registerAttribute(&crossfade_time, new int_attrCB(onSetCrossfadeTime));
+}
+
+Crossfader::~Crossfader() {
+ unhookOutputIPC();
+}
+
diff --git a/Src/Plugins/General/gen_ff/wa2cfgitems.h b/Src/Plugins/General/gen_ff/wa2cfgitems.h
new file mode 100644
index 00000000..6d2959b2
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2cfgitems.h
@@ -0,0 +1,137 @@
+#ifndef _WA2CFGITEMS_H
+#define _WA2CFGITEMS_H
+
+#include <api/config/items/cfgitemi.h>
+#include <api/config/items/attribs.h>
+#include <api/config/items/attrcb.h>
+
+//---------------------------------------------------------
+// playlist editor cfg items
+//---------------------------------------------------------
+class Wa2PlEditCfgItems : public CfgItemI {
+public:
+ Wa2PlEditCfgItems();
+ virtual ~Wa2PlEditCfgItems();
+
+ static void onSetShuffle(BOOL set);
+ static void onSetRepeat(BOOL set);
+};
+
+//---------------------------------------------------------
+// {1828D28F-78DD-4647-8532-EBA504B8FC04}
+static const GUID customOptionsMenuitemGuid =
+{ 0x1828d28f, 0x78dd, 0x4647, { 0x85, 0x32, 0xeb, 0xa5, 0x4, 0xb8, 0xfc, 0x4 } };
+
+// {0542AFA4-48D9-4c9f-8900-5739D52C114F}
+static const GUID skinTweaksGuid =
+{ 0x542afa4, 0x48d9, 0x4c9f, { 0x89, 0x0, 0x57, 0x39, 0xd5, 0x2c, 0x11, 0x4f } };
+
+// {6559CA61-7EB2-4415-A8A9-A2AEEF762B7F}
+static const GUID customWindowsMenuitemGuid =
+{ 0x6559ca61, 0x7eb2, 0x4415, { 0xa8, 0xa9, 0xa2, 0xae, 0xef, 0x76, 0x2b, 0x7f } };
+
+// {F1239F09-8CC6-4081-8519-C2AE99FCB14C}
+static const GUID crossfaderGuid =
+{ 0xf1239f09, 0x8cc6, 0x4081, { 0x85, 0x19, 0xc2, 0xae, 0x99, 0xfc, 0xb1, 0x4c } };
+
+//---------------------------------------------------------
+class CustomOptionsMenuItems : public CfgItemI {
+public:
+ CustomOptionsMenuItems() : CfgItemI(L"Custom OptionsMenu Items", customOptionsMenuitemGuid) { };
+ virtual ~CustomOptionsMenuItems() {}
+};
+
+//---------------------------------------------------------
+class Crossfader : public CfgItemI {
+public:
+ Crossfader();
+ virtual ~Crossfader();
+
+ static void onOutputChanged();
+};
+
+//---------------------------------------------------------
+class AvsCfg : public CfgItemI {
+public:
+ AvsCfg();
+ virtual ~AvsCfg() {}
+
+ static void onVisRandomChanged(BOOL set);
+};
+
+//---------------------------------------------------------
+class CustomWindowsMenuItems : public CfgItemI {
+public:
+ CustomWindowsMenuItems() : CfgItemI(L"Custom WindowsMenu Items", customWindowsMenuitemGuid) { };
+ virtual ~CustomWindowsMenuItems() {}
+};
+
+//---------------------------------------------------------
+class SkinTweaks : public CfgItemI {
+public:
+ SkinTweaks();
+ virtual ~SkinTweaks() {}
+ static void onPreventVideoStopChanged(BOOL set);
+ static void onPreventVideoResize(BOOL set);
+ //static void onDisplayVideoWndOnPlay(BOOL set);
+ //static void onCloseVideoWndOnStop(BOOL set);
+};
+
+//---------------------------------------------------------
+class Wa2CfgItems {
+public:
+ Wa2CfgItems();
+ virtual ~Wa2CfgItems();
+
+private:
+ Wa2PlEditCfgItems pledit;
+};
+
+extern _bool shuffle;
+extern _int repeat;
+extern _bool cfg_audiooptions_crossfader;
+extern _bool cfg_options_alwaysontop;
+extern _bool cfg_uioptions_desktopalpha;
+extern _bool cfg_uioptions_linkratio;
+extern _bool cfg_uioptions_linkalpha;
+extern _bool cfg_uioptions_linkallratio;
+extern _bool cfg_uioptions_linkallalpha;
+extern _bool cfg_uioptions_tooltips;
+extern _float cfg_uioptions_textspeed;
+extern _int cfg_uioptions_textincrement;
+extern _int cfg_uioptions_appbarshidetime;
+extern _int cfg_uioptions_appbarsshowtime;
+extern _int cfg_uioptions_timerresolution;
+extern _bool cfg_audiooptions_crossfader;
+extern _bool cfg_options_altfonts;
+extern _bool cfg_options_allowbitmapfonts;
+extern _string cfg_options_defaultfont;
+extern _string cfg_options_ttfoverridefont;
+extern _int cfg_options_ttfoverridescale;
+extern _int cfg_options_defaultfontscale;
+extern _string cfg_options_fontrenderer;
+extern _bool cfg_options_docking;
+extern _int cfg_options_dockingdistance;
+extern _bool cfg_options_appbarondrag;
+extern _int cfg_options_appbardockingdistance;
+extern _int cfg_options_freetypecharmap;
+extern _bool cfg_options_no7bitsttfoverride;
+extern _bool cfg_options_noalt7bitsttfoverride;
+extern _bool cfg_uioptions_uselocks;
+extern _int cfg_uioptions_autoopacitytime;
+extern _int cfg_uioptions_autoopacitylinked;
+extern _int cfg_uioptions_linkedalpha;
+extern _int cfg_uioptions_autoopacityfadein;
+extern _int cfg_uioptions_autoopacityfadeout;
+extern _int cfg_uioptions_extendautoopacity;
+extern _bool cfg_options_usefontmapper;
+
+extern CustomOptionsMenuItems *optionsmenuitems;
+extern CustomWindowsMenuItems *windowsmenuitems;
+extern SkinTweaks *skintweaks;
+extern int disable_set_wa2_repeat;
+extern StringW eqmenustring;
+
+extern int my_set;
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/wa2core.cpp b/Src/Plugins/General/gen_ff/wa2core.cpp
new file mode 100644
index 00000000..f9526e52
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2core.cpp
@@ -0,0 +1,930 @@
+#include <precomp.h>
+#include "wa2core.h"
+#include "wa2frontend.h"
+#include "../winamp/wa_ipc.h"
+#include "wa2pledit.h"
+#include "../nu/AutoWide.h"
+#include "gen.h"
+#include "../nu/ns_wc.h"
+#include "../Agave/Language/api_language.h"
+#include "../Winamp/in2.h"
+#include "resource.h"
+#include "../nu/AutoChar.h"
+#include <shlwapi.h>
+
+
+
+// {72409F84-BAF1-4448-8211-D84A30A1591A}
+static const GUID eqConfigGroupGUID =
+{ 0x72409f84, 0xbaf1, 0x4448, { 0x82, 0x11, 0xd8, 0x4a, 0x30, 0xa1, 0x59, 0x1a } };
+
+// -----------------------------------------------------------------------------------------------------------------
+// Core implementation for wa2
+// -----------------------------------------------------------------------------------------------------------------
+
+#define TIMER_POLL 0x8971
+
+Core *g_Core = NULL;
+api_core *g_core = NULL;
+int g_coreref = 0;
+
+// this is called by the library when api->core_create is called
+
+api_core *createCustomCoreApi()
+{
+ g_coreref++;
+ if (g_core == NULL) { g_Core = new Core(); g_core = g_Core; }
+ return g_core;
+}
+
+// this is called when api->core_destroy is called
+
+void destroyCustomCoreApi(api_core *core)
+{
+ if (--g_coreref == 0)
+ {
+ delete g_Core;
+ g_Core = NULL;
+ g_core = NULL;
+ }
+}
+
+Core::Core()
+{
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(Agave::AgaveConfigGUID);
+ if (sf)
+ config = (Agave::api_config *)sf->getInterface();
+
+ m_lastpeentry = -1;
+ m_laststatus = -1;
+ m_lastpos = -1;
+ m_lastvol = -1;
+ m_lastpan = -1;
+ m_lasttitle = L"";
+ m_lastsamplerate = -1;
+ m_lastchan = -1;
+ m_lastbitrate = -1;
+ for (int i = 0;i < 10;i++)
+ m_lasteqband[i] = 0xdead;
+ m_lasteq = -1;
+ m_lasteqauto = -1;
+ m_lasteqpreamp = -1;
+ m_lastfreqband = -1;
+ // timerclient_setTimer(TIMER_POLL, 250);
+ gotCallback(IPC_CB_MISC_TITLE, 1);
+ gotCallback(IPC_CB_MISC_VOLUME, 1);
+ gotCallback(IPC_CB_MISC_STATUS, 1);
+ gotCallback(IPC_CB_MISC_EQ, 1);
+ gotCallback(IPC_CB_MISC_INFO, 1);
+ gotCallback(IPC_CB_MISC_TITLE_RATING, 1);
+}
+
+Core::~Core()
+{
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(Agave::AgaveConfigGUID);
+ if (sf)
+ sf->releaseInterface(config);
+ //timerclient_killTimer(TIMER_POLL);
+}
+
+void Core::addCallback(CoreCallback *cb)
+{
+ if (cb == NULL) return ;
+ if (callbacks.haveItem(cb)) return ;
+ callbacks.addItem(cb);
+ cb->ccb_notify(CoreCallback::REGISTER);
+}
+
+void Core::delCallback(CoreCallback *cb)
+{
+ if (cb == NULL) return ;
+ if (callbacks.haveItem(cb))
+ {
+ cb->ccb_notify(CoreCallback::DEREGISTER);
+ callbacks.removeItem(cb);
+ }
+}
+
+void Core::sendCoreCallback(int message, int param1, int param2)
+{
+ ReentryFilter filter(&rf, message);
+ int l = callbacks.getNumItems();
+ for (int i = 0; i < l;i++)
+ callbacks[i]->ccb_notify(message, param1, param2);
+}
+
+int Core::getStatus()
+{
+ return m_laststatus;
+}
+
+void Core::gotCallback(int wParam, int forcecb)
+{
+ if(wParam == IPC_CB_MISC_TITLE_RATING){
+ forcecb = 1;
+ }
+ switch (wParam)
+ {
+ case IPC_CB_MISC_TITLE:
+ case IPC_CB_MISC_TITLE_RATING:
+ {
+ // check for title change
+ wa2.invalidateCache();
+ StringW cur_title=wa2.GetCurrentTitle();
+ if (cur_title.isempty())
+ cur_title = L"";
+
+ StringW cur_file = wa2.GetCurrentFile();
+
+ if (!m_lastfile.iscaseequal(cur_file) || forcecb)
+ {
+ m_lastfile.swap(cur_file);
+ sendCoreCallback(CoreCallback::URLCHANGE, (intptr_t)m_lastfile.getValue());
+ }
+
+ if (!m_lasttitle.iscaseequal(cur_title) || forcecb)
+ {
+ m_lasttitle.swap(cur_title);
+ //Martin> i dunno why we send a INFOCHANGE Callback here, but if we want to send this
+ // callback try to deliver the correct data
+ //sendCoreCallback((forcecb==2?CoreCallback::INFOCHANGE:CoreCallback::TITLECHANGE),
+ // (int)m_lasttitle.getValue(),(wParam == IPC_CB_MISC_TITLE_RATING));
+
+ if (forcecb==2) // this has led to INFOCHANGE Callback
+ {
+ sendCoreCallback(CoreCallback::INFOCHANGE, (intptr_t)getSongInfoText(), (wParam == IPC_CB_MISC_TITLE_RATING));
+ }
+ sendCoreCallback(CoreCallback::TITLECHANGE, (intptr_t)m_lasttitle.getValue(), (wParam == IPC_CB_MISC_TITLE_RATING));
+ }
+
+ int plentry = wa2.getCurPlaylistEntry();
+ int curpeentry = plentry + 1;
+ if (curpeentry != m_lastpeentry)
+ {
+ Wa2PlaylistEditor::_onNewCurrentIndex(curpeentry);
+ m_lastpeentry = curpeentry;
+ }
+ }
+ break;
+ case IPC_CB_MISC_STATUS:
+ {
+ int cur_status;
+ int resume = 0;
+ if (wa2.isPaused()) cur_status = STATUS_PAUSE;
+ else if (wa2.isPlaying())
+ {
+ if (m_laststatus == STATUS_PAUSE)
+ resume = 1;
+ else
+ {
+ m_lastsamplerate = -1;
+ m_lastbitrate = -1;
+ m_lastchan = -1;
+ }
+ cur_status = STATUS_PLAY;
+ }
+ else cur_status = STATUS_STOP;
+
+ if (m_laststatus != cur_status || forcecb)
+ {
+ m_laststatus = cur_status;
+ switch (cur_status)
+ {
+ case STATUS_PLAY: sendCoreCallback(resume ? CoreCallback::UNPAUSED : CoreCallback::STARTED); break;
+ case STATUS_STOP:
+ {
+ m_lastsamplerate = 0;
+ m_lastchan = 0;
+ m_lastbitrate = 0;
+ sendCoreCallback(CoreCallback::STOPPED);
+ break;
+ }
+ case STATUS_PAUSE: sendCoreCallback(CoreCallback::PAUSED); break;
+ }
+ }
+ }
+ break;
+ case IPC_CB_MISC_VOLUME:
+ {
+ // check for volume change
+ int cur_vol = wa2.getVolume();
+ if (m_lastvol != cur_vol || forcecb)
+ {
+ m_lastvol = cur_vol;
+ sendCoreCallback(CoreCallback::VOLCHANGE, cur_vol);
+ }
+ int cur_pan = wa2.getPanning();
+ if (m_lastpan != cur_pan || forcecb)
+ {
+ m_lastpan = cur_pan;
+ sendCoreCallback(CoreCallback::PANCHANGE, cur_pan);
+ }
+ }
+ break;
+ case IPC_CB_MISC_EQ:
+ {
+ // check if the band frequencies changed (winamp vs ISO)
+ int new_freqband = config->GetInt(eqConfigGroupGUID, L"frequencies", 0);
+ if (m_lastfreqband != new_freqband)
+ {
+ bool sendCallback = m_lastfreqband != -1;
+
+ m_lastfreqband = new_freqband; // set before the callback so we don't run into any issues if the callback triggers another EQ change message
+ if (sendCallback)
+ sendCoreCallback(CoreCallback::EQFREQCHANGE, new_freqband, 0);
+ }
+
+ // check for eq change
+ for (int i = 0;i < 10;i++)
+ {
+ int cur_band = wa2.getEqData(WA2_EQDATA_FIRSTBAND + i);
+ if (cur_band == 63 - ((m_lasteqband[i] + 127) / 4)) cur_band = m_lasteqband[i];
+ else cur_band = (63 - cur_band) * 4 - 127;
+ if (m_lasteqband[i] != cur_band || forcecb)
+ {
+ m_lasteqband[i] = cur_band;
+ sendCoreCallback(CoreCallback::EQBANDCHANGE, i, cur_band);
+ }
+ }
+ int cur_eq = wa2.getEqData(WA2_EQDATA_ENABLED);
+ if (m_lasteq != cur_eq)
+ {
+ m_lasteq = cur_eq;
+ sendCoreCallback(CoreCallback::EQSTATUSCHANGE, cur_eq);
+ }
+ int cur_eqauto = wa2.getEqData(WA2_EQDATA_AUTO);
+ if (m_lasteqauto != cur_eqauto || forcecb)
+ {
+ m_lasteqauto = cur_eqauto;
+ sendCoreCallback(CoreCallback::EQAUTOCHANGE, cur_eqauto);
+ }
+ int cur_eqpreamp = wa2.getEqData(WA2_EQDATA_PREAMP);
+ if (cur_eqpreamp == 63 - ((cur_eqpreamp + 127) / 4)) { /*cur_eqpreamp = cur_eqpreamp;*/ }
+ else cur_eqpreamp = (63 - cur_eqpreamp) * 4 - 127;
+ if (m_lasteqpreamp != cur_eqpreamp || forcecb)
+ {
+ m_lasteqpreamp = cur_eqpreamp;
+ sendCoreCallback(CoreCallback::EQPREAMPCHANGE, cur_eqpreamp);
+ }
+ }
+ break;
+
+ case IPC_CB_MISC_INFO:
+ {
+ int realrate = wa2.getSamplerate();
+ int brate = wa2.getBitrate();
+ int ch = wa2.getChannels();
+ int any = 0;
+ if (realrate != m_lastsamplerate || forcecb)
+ {
+ m_lastsamplerate = realrate;
+ sendCoreCallback(CoreCallback::SAMPLERATECHANGE, realrate);
+ any = 1;
+ }
+ if (brate != m_lastbitrate || forcecb)
+ {
+ m_lastbitrate = brate;
+ sendCoreCallback(CoreCallback::BITRATECHANGE, m_lastbitrate);
+ any = 1;
+ }
+ if (ch != m_lastchan || forcecb)
+ {
+ m_lastchan = ch;
+ sendCoreCallback(CoreCallback::CHANNELSCHANGE, m_lastchan);
+ any = 1;
+ }
+ //DebugString("Got IPC_CB_MISC_INFO callback, numchans = %d, samplerate = %d, bitrate = %d\n", m_lastchan, m_lastsamplerate, m_lastbitrate);
+ if (any)
+ {
+ StringW txt = getSongInfoText();
+ sendCoreCallback(CoreCallback::INFOCHANGE, (intptr_t)txt.getValue());
+ }
+ break;
+ }
+ }
+}
+
+StringW infotext;
+
+const wchar_t *Core::getSongInfoText()
+{
+ infotext = L"";
+ int srate = wa2.getSamplerate();
+ int brate = wa2.getBitrate();
+ int ch = wa2.getChannels();
+
+ if (srate == 0 && brate == 0)
+ {
+ return L"";
+ }
+
+ infotext = StringPrintfW(L"%dkbps", brate);
+
+ if (ch == 1)
+ {
+ infotext += L" mono";
+ }
+ else if (ch == 2)
+ {
+ infotext += L" stereo";
+ }
+ else if (ch > 2)
+ {
+ infotext += StringPrintfW(L" %d Channels", ch);
+ }
+
+ infotext += StringPrintfW(L" %.1fkHz", (float)srate/1000.0f);
+
+ if (wa2.isPlayingVideo())
+ {
+ infotext.prepend(L"Video ");
+ }
+ return infotext;
+}
+
+StringW infotextTranslated;
+
+const wchar_t *Core::getSongInfoTextTranslated()
+{
+ infotextTranslated = L"";
+ int srate = wa2.getSamplerate();
+ int brate = wa2.getBitrate();
+ int ch = wa2.getChannels();
+
+ if (srate == 0 && brate == 0)
+ {
+ return L"";
+ }
+
+ infotextTranslated = StringPrintfW(L"%d%s", brate,WASABI_API_LNGSTRINGW(IDS_KBPS));
+
+ if (ch == 1)
+ {
+ infotextTranslated += WASABI_API_LNGSTRINGW(IDS_MONO);
+ }
+ else if (ch == 2)
+ {
+ infotextTranslated += WASABI_API_LNGSTRINGW(IDS_STEREO);
+ }
+ else if (ch > 2)
+ {
+ infotextTranslated += StringPrintfW(WASABI_API_LNGSTRINGW(IDS_X_CHANNELS), ch);
+ }
+
+ infotextTranslated += StringPrintfW(L" %.1f", (float)srate/1000.0f);
+ infotextTranslated += WASABI_API_LNGSTRINGW(IDS_KHZ);// (doing this in the StringPrintfW(..) above causes a crash even in a seperate buffer)
+
+ if (wa2.isPlayingVideo())
+ {
+ infotextTranslated.prepend(StringPrintfW(L"%s ",WASABI_API_LNGSTRINGW(IDS_VIDEO)));
+ }
+
+ return infotextTranslated;
+}
+
+void Core::userButton(int button)
+{
+ int mod = Std::keyDown(VK_SHIFT) ? WA2_USERBUTTONMOD_SHIFT : (Std::keyDown(VK_SHIFT) ? WA2_USERBUTTONMOD_CTRL : WA2_USERBUTTONMOD_NONE);
+ switch (button)
+ {
+ case UserButton::PLAY: wa2.userButton(WA2_USERBUTTON_PLAY, mod); break;
+ case UserButton::STOP: wa2.userButton(WA2_USERBUTTON_STOP, mod); break;
+ case UserButton::PAUSE: wa2.userButton(WA2_USERBUTTON_PAUSE, mod); break;
+ case UserButton::NEXT: wa2.userButton(WA2_USERBUTTON_NEXT, mod); break;
+ case UserButton::PREV: wa2.userButton(WA2_USERBUTTON_PREV, mod); break;
+ }
+}
+
+void Core::setVolume(int vol)
+{
+ wa2.setVolume(vol);
+}
+
+int Core::getVolume()
+{
+ return wa2.getVolume();
+}
+
+void Core::setPosition(int ms)
+{
+ wa2.seekTo(ms);
+ sendCoreCallback(CoreCallback::SEEKED, ms);
+}
+
+int Core::getPosition()
+{
+ if (m_laststatus == STATUS_STOP) return -1;
+ return wa2.getPosition();
+}
+
+int Core::getLength()
+{
+ if (m_laststatus == STATUS_STOP) return -1;
+ return wa2.getLength();
+}
+
+void Core::setPanning(int p)
+{
+ if (p > 127) p = 127;
+ wa2.setPanning(p);
+}
+
+int Core::getPanning()
+{
+ return wa2.getPanning();
+}
+
+void Core::setShuffle(int shuffle)
+{
+ wa2.setShuffle(shuffle);
+}
+
+int Core::getShuffle()
+{
+ return wa2.getShuffle();
+}
+
+void Core::setRepeat(int repeat)
+{
+ static int myset = 0;
+ if (!myset)
+ {
+ myset = 1;
+ int manadv = 0;
+ int rep = 0;
+ if (repeat == 0)
+ {
+ rep = 0;
+ manadv = 0;
+ }
+ else if (repeat > 0)
+ {
+ rep = 1;
+ manadv = 0;
+ }
+ else if (repeat < 0)
+ {
+ rep = 1;
+ manadv = 1;
+ }
+ if (!!wa2.getRepeat() != !!rep) wa2.setRepeat(rep);
+ if (!!wa2.getManualPlaylistAdvance() != !!manadv) wa2.setManualPlaylistAdvance(manadv);
+ myset = 0;
+ }
+}
+
+int Core::getRepeat()
+{
+ int manadv = wa2.getManualPlaylistAdvance();
+ int rep = wa2.getRepeat();
+ int _v = (rep && manadv) ? -1 : rep;
+ return _v;
+}
+
+int Core::getSamplerate(int wa2_getinfo)
+{
+ return wa2.getInfo(WA2_GETINFO_SAMPLERATE);
+}
+
+int Core::getBitrate(int wa2_getinfo)
+{
+ return wa2.getInfo(WA2_GETINFO_BITRATE);
+}
+
+int Core::getChannels(int wa2_getinfo)
+{
+ return wa2.getInfo(WA2_GETINFO_CHANNELS);
+}
+
+int Core::getEqBand(int band)
+{
+ // int v = 63-wa2.getEqData(WA2_EQDATA_FIRSTBAND+band) * 4 - 127;
+ // v = MIN(-127, v);
+ // v = MAX(127, v);
+ return m_lasteqband[band]; //(v);
+}
+
+void Core::setEqBand(int band, int val)
+{
+ val = MIN(127, MAX( -127, val));
+ m_lasteqband[band] = val;
+ int v = 63 - ((val + 127) / 4);
+ v = MIN(63, v);
+ v = MAX(0, v);
+ wa2.setEqData(WA2_EQDATA_FIRSTBAND + band, v);
+ sendCoreCallback(CoreCallback::EQBANDCHANGE, band, val);
+}
+
+int Core::getEQStatus()
+{
+ return wa2.getEqData(WA2_EQDATA_ENABLED);
+}
+
+void Core::setEQStatus(int enable)
+{
+ wa2.setEqData(WA2_EQDATA_ENABLED, enable);
+}
+
+int Core::getEQAuto()
+{
+ return wa2.getEqData(WA2_EQDATA_AUTO);
+}
+
+void Core::setEQAuto(int enable)
+{
+ wa2.setEqData(WA2_EQDATA_AUTO, enable);
+}
+
+int Core::getEQPreamp()
+{
+ // int v = 63-wa2.getEqData(WA2_EQDATA_PREAMP) * 4 - 127;
+ // v = MIN(-127, v);
+ // v = MAX(127, v);
+ return m_lasteqpreamp;
+}
+
+void Core::setEQPreamp(int val)
+{
+ val = MIN(127, MAX( -127, val));
+ m_lasteqpreamp = val;
+ int v = 63 - ((val + 127) / 4);
+ v = MIN(63, v);
+ v = MAX(0, v);
+ wa2.setEqData(WA2_EQDATA_PREAMP, v);
+ sendCoreCallback(CoreCallback::EQPREAMPCHANGE, val);
+}
+
+const wchar_t *Core::getTitle()
+{
+ return m_lasttitle; // faster to use our cached ver
+ // int plentry = wa2.getCurPlaylistEntry();
+ // if (plentry == -1) return NULL;
+ // return wa2.getTitle(plentry);
+}
+
+void Core::setTitle(const wchar_t * new_title)
+{
+ StringW title = new_title;
+ if(title.isempty())
+ title = L"";
+ m_lasttitle = title;
+}
+
+const wchar_t *Core::getPlaystring()
+{
+ m_playstring = wa2.GetCurrentFile();
+ if (m_playstring.getValue() == NULL) m_playstring = L"";
+ return m_playstring;
+}
+
+int Core::getCurPlaylistEntry()
+{
+ return wa2.getCurPlaylistEntry();
+}
+
+// -----------------------------------------------------------------------------------------------------------------
+// api_core implementation
+// -----------------------------------------------------------------------------------------------------------------
+
+// this pointer is set automagically by ApiInit
+api_core *coreApi = NULL;
+
+const wchar_t *Core::core_getSupportedExtensions()
+{
+ return L"mp3\x0";
+}
+
+const wchar_t *Core::core_getExtSupportedExtensions()
+{
+ return L"mp3\x0";
+}
+
+CoreToken Core::core_create()
+{
+ return 0;
+}
+
+int Core::core_free(CoreToken core)
+{
+ return 0;
+}
+
+int Core::core_setNextFile(CoreToken core, const wchar_t *playstring)
+{
+ return 0;
+}
+
+int Core::core_getStatus(CoreToken core)
+{
+ switch (getStatus())
+ {
+ case STATUS_STOP : return 0;
+ case STATUS_PLAY : return 1;
+ case STATUS_PAUSE : return -1;
+ }
+ return 0; // dunno, stopped i guess...
+}
+
+const wchar_t *Core::core_getCurrent(CoreToken core)
+{
+ return getPlaystring();
+}
+
+int Core::core_getCurPlaybackNumber(CoreToken core)
+{
+ return getCurPlaylistEntry();
+}
+
+int Core::core_getPosition(CoreToken core)
+{
+ return getPosition();
+}
+
+int Core::core_getWritePosition(CoreToken core)
+{
+ return getPosition();
+}
+
+int Core::core_setPosition(CoreToken core, int ms)
+{
+ setPosition(ms);
+ return 1;
+}
+
+int Core::core_getLength(CoreToken core)
+{
+ return getLength();
+}
+
+int Core::core_getPluginData(const wchar_t *playstring, const wchar_t *name, wchar_t *data, int data_len, int data_type)
+{
+ return 0;
+}
+
+unsigned int Core::core_getVolume(CoreToken core)
+{
+ return getVolume();
+}
+
+void Core::core_setVolume(CoreToken core, unsigned int vol)
+{
+ setVolume(vol);
+}
+
+int Core::core_getPan(CoreToken core)
+{
+ return getPanning();
+}
+
+void Core::core_setPan(CoreToken core, int val)
+{
+ setPanning(val);
+}
+
+void Core::core_addCallback(CoreToken core, CoreCallback *cb)
+{
+ addCallback(cb);
+}
+
+void Core::core_delCallback(CoreToken core, CoreCallback *cb)
+{
+ delCallback(cb);
+}
+
+int Core::core_getVisData(CoreToken core, void *dataptr, int sizedataptr)
+{
+ int ret = 75*2;
+ // added this to attempt to cope with some poor / old input plug-ins
+ // which keep cropping up in the plug-in crash reports from users...
+ try
+ {
+ // todo
+ if (wa2.export_sa_get)
+ {
+ if (sizedataptr >= (75*2 + 8))
+ wa2.export_sa_get((char *)dataptr);
+ else
+ {
+ char data[75*2 + 8];
+ char *p = wa2.export_sa_get(data);
+ if (p) memcpy(dataptr, p, min(2*75, sizedataptr));
+ }
+ }
+ else if (wa2.export_sa_get_deprecated)
+ {
+ char *p = wa2.export_sa_get_deprecated();
+ if (p) memcpy(dataptr, p, min(2*75, sizedataptr));
+ }
+ }
+ catch(...)
+ {
+ ret = 0;
+ }
+ return ret;
+}
+
+int Core::core_getLeftVuMeter(CoreToken core)
+{
+ if (wa2.export_vu_get)
+ {
+ int vu = wa2.export_vu_get(0);
+ if (vu != -1)
+ return vu;
+ }
+ if (wa2.export_sa_get)
+ {
+ char data[75*2 + 8] = {0};
+ char *p = (char *)wa2.export_sa_get(data);
+ if (!p) return 0;
+
+ int m = 0;
+ for (int i = 75;i < 150;i++) // this is very gay but workish
+ m = max(abs(m), p[i]);
+
+ return MIN(255, m*16);
+ }
+ else if (wa2.export_sa_get_deprecated)
+ {
+ char *p = (char *)wa2.export_sa_get_deprecated();
+ if (!p) return 0;
+
+ int m = 0;
+ for (int i = 75;i < 150;i++) // this is very gay but workish
+ m = max(abs(m), p[i]);
+
+ return MIN(255, m*16);
+ }
+ else return 0;
+
+}
+
+int Core::core_getRightVuMeter(CoreToken core)
+{
+ if (wa2.export_vu_get)
+ {
+ int vu = wa2.export_vu_get(1);
+ if (vu == -1)
+ vu = wa2.export_vu_get(0);
+ if (vu != -1)
+ return vu;
+ }
+
+ return core_getLeftVuMeter(core);
+}
+
+int Core::core_registerSequencer(CoreToken core, ItemSequencer *seq)
+{
+ return 0;
+}
+
+int Core::core_deregisterSequencer(CoreToken core, ItemSequencer *seq)
+{
+ return 0;
+}
+
+void Core::core_userButton(CoreToken core, int button)
+{
+ userButton(button);
+}
+
+int Core::core_getEqStatus(CoreToken core)
+{
+ return getEQStatus();
+}
+
+void Core::core_setEqStatus(CoreToken core, int enable)
+{
+ setEQStatus(enable);
+}
+
+int Core::core_getEqPreamp(CoreToken core)
+{
+ return getEQPreamp();
+}
+
+void Core::core_setEqPreamp(CoreToken core, int pre)
+{
+ setEQPreamp(pre);
+}
+
+int Core::core_getEqBand(CoreToken core, int band)
+{
+ return getEqBand(band);
+}
+
+void Core::core_setEqBand(CoreToken core, int band, int val)
+{
+ setEqBand(band, val);
+}
+
+int Core::core_getEqAuto(CoreToken core)
+{
+ return getEQAuto();
+}
+
+void Core::core_setEqAuto(CoreToken core, int enable)
+{
+ setEQAuto(enable);
+}
+
+void Core::core_setCustomMsg(CoreToken core, const wchar_t *text)
+{}
+
+void Core::core_registerExtension(const wchar_t *extensions, const wchar_t *extension_name, const wchar_t *family)
+{}
+
+
+const wchar_t *Core::core_getDecoderName(const wchar_t *filename)
+{
+ wchar_t fn[MAX_PATH+3] = {0};
+ WCSNPRINTF(fn, MAX_PATH, L"hi.%s", filename);
+ In_Module *player = (In_Module *)wa2.CanPlay(fn);
+ if (player)
+ {
+ // cope nicely with the 5.64+ input plug-ins with unicode descriptions
+ static wchar_t decoder_name[512];
+ int ver = ((player->version & ~IN_UNICODE) & ~IN_INIT_RET);
+ if (ver == IN_VER)
+ {
+ StringCchCopyW(decoder_name, 512, (wchar_t *)player->description);
+ }
+ else
+ {
+ MultiByteToWideCharSZ(CP_ACP, 0, player->description, -1, decoder_name, 512);
+ }
+ return decoder_name;
+ }
+ return NULL;
+}
+
+const wchar_t *Core::core_getExtensionFamily(const wchar_t *extension)
+{
+ wchar_t fn[MAX_PATH] = {0};
+ WCSNPRINTF(fn, MAX_PATH, L"hi.%s", extension);
+ In_Module *player = (In_Module *)wa2.CanPlay(fn);
+ if (player)
+ {
+ /*
+ char *p = player->FileExtensions;
+ const wchar_t *realExt = PathFindExtensionW(fn);
+ if (realExt && *realExt)
+ realExt++;
+ AutoChar ext(realExt);
+ while (p && *p)
+ {
+ char *b = p;
+ char *c;
+ do
+ {
+ char d[20] = {0};
+ lstrcpyn(d, b, 15);
+ if ((c = strstr(b, ";")))
+ {
+ if ((c-b)<15)
+ d[c - b] = 0;
+ }
+
+ if (!_stricmp(ext, d))
+ {
+ p += lstrlen(p) + 1; // skip to the name
+ MultiByteToWideCharSZ(CP_ACP, 0, p, -1, family, 512);
+ return family;
+ }
+ b = c + 1;
+ }
+ while (c);
+ p += lstrlen(p) + 1;
+ if (!*p) break;
+ p += lstrlen(p) + 1;
+ }
+
+*/
+ static wchar_t family[512];
+ MultiByteToWideCharSZ(CP_ACP, 0, player->description, -1, family, 512);
+ return family;
+ }
+ return NULL;
+}
+
+void Core::core_unregisterExtension(const wchar_t *extensions)
+{}
+
+const wchar_t *Core::core_getTitle(CoreToken core)
+{
+ return getTitle();
+}
+
+void Core::core_setTitle(const wchar_t *new_title)
+{
+ setTitle(new_title);
+}
+
+int Core::core_getRating()
+{
+ return wa2.getCurTrackRating();
+}
+
+void Core::core_setRating(int newRating)
+{
+ wa2.setCurTrackRating(newRating);
+}
diff --git a/Src/Plugins/General/gen_ff/wa2core.h b/Src/Plugins/General/gen_ff/wa2core.h
new file mode 100644
index 00000000..36fce556
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2core.h
@@ -0,0 +1,147 @@
+#ifndef __GENFF_CORE_H
+#define __GENFF_CORE_H
+
+#include <bfc/string/StringW.h>
+//#include "../studio/bfc/timerclient.h"
+#include <api/core/buttons.h>
+#include <api/syscb/callbacks/corecbi.h>
+#include <api/core/api_core.h>
+namespace Agave
+{
+ #include "../Agave/Config/api_config.h"
+}
+
+#define STATUS_UNKNOWN -1
+#define STATUS_STOP 0
+#define STATUS_PLAY 1
+#define STATUS_PAUSE 2
+
+class Core : public api_coreI//, public CoreCallbackI
+{ //, public TimerClientDI {
+public:
+ Core();
+ virtual ~Core();
+
+ void gotCallback(int wParam, int forcecb = 0);
+
+ void addCallback(CoreCallback *cb);
+ void delCallback(CoreCallback *cb);
+
+ // virtual void timerclient_timerCallback(int id);
+
+ int getStatus();
+ void userButton(int button);
+
+ void setVolume(int vol);
+ int getVolume();
+
+ void setPosition(int ms);
+ int getPosition();
+ int getLength();
+
+ void setPanning(int p);
+ int getPanning();
+
+ void setShuffle(int shuffle);
+ int getShuffle();
+
+ void setRepeat(int repeat);
+ int getRepeat();
+
+ int getSamplerate(int wa2_getinfo);
+ int getBitrate(int wa2_getinfo);
+ int getChannels(int wa2_getinfo);
+
+ int getEqBand(int band);
+ void setEqBand(int band, int val);
+
+ int getEQStatus();
+ void setEQStatus(int enable);
+
+ int getEQAuto();
+ void setEQAuto(int enable);
+
+ int getEQPreamp();
+ void setEQPreamp(int enable);
+
+ const wchar_t *getTitle();
+ void setTitle(const wchar_t * new_title);
+ const wchar_t *getPlaystring();
+
+ int getCurPlaylistEntry();
+
+ static const wchar_t *getSongInfoText();
+ static const wchar_t *getSongInfoTextTranslated();
+
+ // api_core ------------------------------------------------------------------------
+
+
+ virtual const wchar_t *core_getSupportedExtensions();
+ virtual const wchar_t *core_getExtSupportedExtensions();
+ virtual CoreToken core_create();
+ virtual int core_free(CoreToken core);
+ virtual int core_setNextFile(CoreToken core, const wchar_t *playstring);
+ virtual int core_getStatus(CoreToken core);
+ virtual const wchar_t *core_getCurrent(CoreToken core);
+ virtual int core_getCurPlaybackNumber(CoreToken core);
+ virtual int core_getPosition(CoreToken core);
+ virtual int core_getWritePosition(CoreToken core);
+ virtual int core_setPosition(CoreToken core, int ms);
+ virtual int core_getLength(CoreToken core);
+ virtual int core_getPluginData(const wchar_t *playstring, const wchar_t *name, wchar_t *data, int data_len, int data_type = 0);
+ virtual unsigned int core_getVolume(CoreToken core);
+ virtual void core_setVolume(CoreToken core, unsigned int vol);
+ virtual int core_getPan(CoreToken core);
+ virtual void core_setPan(CoreToken core, int val);
+ virtual void core_addCallback(CoreToken core, CoreCallback *cb);
+ virtual void core_delCallback(CoreToken core, CoreCallback *cb);
+ virtual int core_getVisData(CoreToken core, void *dataptr, int sizedataptr);
+ virtual int core_getLeftVuMeter(CoreToken core);
+ virtual int core_getRightVuMeter(CoreToken core);
+ virtual int core_registerSequencer(CoreToken core, ItemSequencer *seq);
+ virtual int core_deregisterSequencer(CoreToken core, ItemSequencer *seq);
+ virtual void core_userButton(CoreToken core, int button);
+ virtual int core_getEqStatus(CoreToken core);
+ virtual void core_setEqStatus(CoreToken core, int enable);
+ virtual int core_getEqPreamp(CoreToken core);
+ virtual void core_setEqPreamp(CoreToken core, int pre);
+ virtual int core_getEqBand(CoreToken core, int band);
+ virtual void core_setEqBand(CoreToken core, int band, int val);
+ virtual int core_getEqAuto(CoreToken core);
+ virtual void core_setEqAuto(CoreToken core, int enable);
+ virtual void core_setCustomMsg(CoreToken core, const wchar_t *text);
+ virtual void core_registerExtension(const wchar_t *extensions, const wchar_t *extension_name, const wchar_t *family = NULL);
+ virtual const wchar_t *core_getExtensionFamily(const wchar_t *extension);
+ virtual void core_unregisterExtension(const wchar_t *extensions);
+ virtual const wchar_t *core_getTitle(CoreToken core);
+ virtual void core_setTitle(const wchar_t *new_title);
+ const wchar_t *core_getDecoderName(const wchar_t *Filename);
+ virtual int core_getRating();
+ virtual void core_setRating(int newRating);
+
+private:
+ void sendCoreCallback(int message, int param1 = 0, int param2 = 0);
+ StringW m_lasttitle;
+ StringW m_playstring, m_lastfile;
+ int m_laststatus;
+ int m_lastpos;
+ int m_lastvol;
+ int m_lastpan;
+ int m_lasteqband[10];
+ int m_lastfreqband;
+ int m_lasteq;
+ int m_lasteqauto;
+ int m_lasteqpreamp;
+ int m_lastchan;
+ int m_lastbitrate;
+ int m_lastsamplerate;
+ int m_lastpeentry;
+
+ PtrList<CoreCallback> callbacks;
+ ReentryFilterObject rf;
+ Agave::api_config *config;
+};
+
+extern Core *g_Core;
+
+#endif
diff --git a/Src/Plugins/General/gen_ff/wa2coreactions.cpp b/Src/Plugins/General/gen_ff/wa2coreactions.cpp
new file mode 100644
index 00000000..218342b2
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2coreactions.cpp
@@ -0,0 +1,279 @@
+#include <precomp.h>
+#include "wa2frontend.h"
+#include "wa2core.h"
+#include "wa2coreactions.h"
+#include "main.h"
+#include <api/core/api_core.h>
+#include <api/locales/xlatstr.h>
+
+//-----------------------------------------------------------------------------------------------
+CoreActions::CoreActions()
+{
+ registerAction( L"prev", ACTION_PREV );
+ registerAction( L"play", ACTION_PLAY );
+ registerAction( L"pause", ACTION_PAUSE );
+ registerAction( L"stop", ACTION_STOP );
+ registerAction( L"next", ACTION_NEXT );
+ registerAction( L"eject", ACTION_EJECT );
+ registerAction( L"eject_url", ACTION_EJECTURL );
+ registerAction( L"eject_dir", ACTION_EJECTDIR );
+ registerAction( L"seek", ACTION_SEEK );
+ registerAction( L"volume", ACTION_VOLUME );
+ registerAction( L"pan", ACTION_PAN );
+ registerAction( L"volume_up", ACTION_VOLUME_UP );
+ registerAction( L"volume_down", ACTION_VOLUME_DOWN );
+ registerAction( L"rewind_5s", ACTION_REWIND_5S );
+ registerAction( L"ffwd_5s", ACTION_FFWD_5S );
+ registerAction( L"toggle_repeat", ACTION_TOGGLE_REPEAT );
+ registerAction( L"toggle_shuffle", ACTION_TOGGLE_SHUFFLE );
+ registerAction( L"toggle_crossfader", ACTION_TOGGLE_CROSSFADER );
+ registerAction( L"mute", ACTION_MUTE );
+ registerAction( L"eq_toggle", ACTION_EQ_TOGGLE );
+ registerAction( L"eq_preamp", ACTION_EQ_PREAMP );
+ registerAction( L"eq_band", ACTION_EQ_BAND );
+ registerAction( L"eq_auto", ACTION_EQ_AUTO );
+ registerAction( L"eq_reset", ACTION_EQ_RESET );
+ // these were duped?
+ // yes, for wa3alpha skins compatibility
+ registerAction( L"toggle_repeat", ACTION_TOGGLE_REPEAT );
+ registerAction( L"toggle_shuffle", ACTION_TOGGLE_SHUFFLE );
+ registerAction( L"toggle_crossfader", ACTION_TOGGLE_CROSSFADER );
+ for ( int i = 0; i < 4; i++ )
+ registerAction( StringPrintfW( L"play_cd%d", i + 1 ), ACTION_PLAY_CD + i );
+ // Martin> Moved from menuaction.cpp
+ registerAction( L"WA5:Prefs", ACTION_PREFS );
+}
+
+//-----------------------------------------------------------------------------------------------
+CoreActions::~CoreActions()
+{}
+
+
+//-----------------------------------------------------------------------------------------------
+int CoreActions::onActionId(int pvtid, const wchar_t *action, const wchar_t *param /* =NULL */, int p1 /* =0 */, int p2 /* =0 */, void *data /* =NULL */, int datalen /* =0 */, ifc_window *source /* =NULL */)
+{
+ if (g_Core == NULL) return 0;
+ int a = WTOI(param);
+ switch (pvtid)
+ {
+ case ACTION_PREV:
+ if (Std::keyDown(VK_SHIFT))
+ {
+ wa2.rewind5s();
+ }
+ else if (Std::keyDown(VK_CONTROL))
+ {
+ wa2.startOfPlaylist();
+ }
+ else
+ {
+ if (a)
+ wa2.previousPopupMenu();
+ else
+ g_Core->userButton(UserButton::PREV);
+ }
+ break;
+ case ACTION_PLAY:
+ if (Std::keyDown(VK_SHIFT))
+ {
+ wa2.openFileDialog(source ? source->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd());
+ }
+ else if (Std::keyDown(VK_CONTROL))
+ {
+ wa2.openUrlDialog(source ? source->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd());
+ }
+ else
+ {
+ if (a)
+ wa2.playPopupMenu();
+ else
+ g_Core->userButton(UserButton::PLAY);
+ }
+ break;
+ case ACTION_PAUSE:
+ if (a)
+ wa2.pausePopupMenu();
+ else
+ g_Core->userButton(UserButton::PAUSE);
+ break;
+ case ACTION_STOP:
+ if (Std::keyDown(VK_SHIFT))
+ {
+ wa2.stopWithFade();
+ }
+ else if (Std::keyDown(VK_CONTROL))
+ {
+ wa2.stopAfterCurrent();
+ }
+ else
+ {
+ if (a)
+ wa2.stopPopupMenu();
+ else
+ g_Core->userButton(UserButton::STOP);
+ }
+ break;
+ case ACTION_NEXT:
+ if (Std::keyDown(VK_SHIFT))
+ {
+ wa2.forward5s();
+ }
+ else if (Std::keyDown(VK_CONTROL))
+ {
+ wa2.endOfPlaylist();
+ }
+ else
+ {
+ if (a)
+ wa2.nextPopupMenu();
+ else if (a == 0)
+ g_Core->userButton(UserButton::NEXT);
+ }
+ break;
+ case ACTION_EJECT:
+ if (Std::keyDown(VK_SHIFT))
+ {
+ wa2.openDirectoryDialog(source ? source->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd());
+ }
+ else if (Std::keyDown(VK_CONTROL))
+ {
+ wa2.openUrlDialog(source ? source->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd());
+ }
+ else
+ {
+ if (a)
+ wa2.ejectPopupMenu();
+ else
+ wa2.openFileDialog(source ? source->gethWnd() : wa2.getMainWindow());
+ }
+ break;
+ case ACTION_EJECTURL:
+ if (a == 0)
+ {
+ wa2.openUrlDialog(source ? source->gethWnd() : wa2.getMainWindow()); break;
+ }
+ else return 0;
+ case ACTION_EJECTDIR:
+ if (a == 0)
+ {
+ wa2.openDirectoryDialog(source ? source->gethWnd() : wa2.getMainWindow()); break;
+ }
+ else return 0;
+ case ACTION_VOLUME_UP:
+ if (a == 0)
+ {
+ g_Core->setVolume(MIN(g_Core->getVolume() + 5, 255)); break;
+ }
+ else return 0;
+ case ACTION_VOLUME_DOWN:
+ if (a == 0)
+ {
+ g_Core->setVolume(MIN(g_Core->getVolume() - 5, 255)); break;
+ }
+ else return 0;
+ case ACTION_REWIND_5S:
+ if (a == 0)
+ {
+ g_Core->setPosition(MAX(g_Core->getPosition() - 5000, 0)); break;
+ }
+ else return 0;
+ case ACTION_FFWD_5S:
+ if (a == 0)
+ {
+ g_Core->setPosition(MIN(g_Core->getPosition() + 5000, g_Core->getLength())); break;
+ }
+ else return 0;
+ case ACTION_EQ_AUTO:
+ if (a == 0)
+ {
+ g_Core->setEQAuto(!g_Core->getEQAuto()); break;
+ }
+ else return 0;
+ case ACTION_EQ_TOGGLE:
+ if (a == 0)
+ {
+ g_Core->setEQStatus(!g_Core->getEQStatus()); break;
+ }
+ else return 0;
+ case ACTION_EQ_RESET:
+ if (a == 0)
+ {
+ {
+ for (int i = 0;i < 10;i++) g_Core->setEqBand(i, 0);
+ }
+ break;
+ }
+ else return 0;
+ //case ACTION_MUTE: g_Core->setMute(!g_Core->getMute()); break;
+ case ACTION_TOGGLE_REPEAT:
+ if (a == 0)
+ {
+ wa2.setRepeat(!wa2.getRepeat());
+ }
+ else return 0;
+ break;
+ case ACTION_TOGGLE_SHUFFLE:
+ if (a == 0)
+ {
+ wa2.setShuffle(!wa2.getShuffle());
+ }
+ else
+ return 0;
+ break;
+ case ACTION_TOGGLE_CROSSFADER:
+ break; // todo
+ // Martin> Moved from menuactions.cpp
+ case ACTION_PREFS:
+ {
+ // check if param is set, otherwise we will get a crash
+ if (param != NULL)
+ {
+ int prefsPage = _wtoi(param);
+ SendMessageW(wa2.getMainWindow(),WM_WA_IPC,prefsPage,IPC_OPENPREFSTOPAGE);
+ }
+ break;
+ }
+ }
+ if (pvtid >= ACTION_PLAY_CD && pvtid < ACTION_PLAY_CD + 16)
+ {
+ if (a == 0)
+ {
+ wa2.playAudioCD(pvtid - ACTION_PLAY_CD);
+ }
+ else return 0;
+ }
+ return 1;
+}
+
+const wchar_t *CoreActions::getHelp(int action)
+{
+ static StringW name;
+ switch (action)
+ {
+ // TODO: benski> move to win32 resources and let them get translated via gen_ff.lng
+ case ACTION_PREV: name = _(L"Previous track"); break;
+ case ACTION_PAUSE: name = _(L"Pause/Resume playback"); break;
+ case ACTION_STOP: name = _(L"Stop playback"); break;
+ case ACTION_NEXT: name = _(L"Next track"); break;
+ case ACTION_EJECT: name = _(L"Load file"); break;
+ case ACTION_EJECTURL: name = _(L"Load URL"); break;
+ case ACTION_EJECTDIR: name = _(L"Load directory"); break;
+ case ACTION_SEEK: name = _(L"Seek"); break;
+ case ACTION_VOLUME: name = _(L"Volume"); break;
+ case ACTION_PAN: name = _(L"Panning"); break;
+ case ACTION_EQ_TOGGLE: name = _(L"Toggle equalizer"); break;
+ case ACTION_EQ_PREAMP: name = _(L"Toggle preamplifier"); break;
+ case ACTION_EQ_BAND: name = _(L"Change equalizer band"); break;
+ case ACTION_EQ_AUTO: name = _(L"Auto equalizer"); break;
+ case ACTION_EQ_RESET: name = _(L"Reset equalizer"); break;
+ case ACTION_VOLUME_UP: name = _(L"Volume up"); break;
+ case ACTION_VOLUME_DOWN: name = _(L"Volume down"); break;
+ case ACTION_REWIND_5S: name = _(L"Rewind 5 seconds"); break;
+ case ACTION_FFWD_5S: name = _(L"Fast forward 5 seconds"); break;
+ case ACTION_MUTE: name = _(L"Mute/Unmute sound"); break;
+ case ACTION_TOGGLE_REPEAT: name = _(L"Toggle repeat"); break;
+ case ACTION_TOGGLE_SHUFFLE: name = _(L"Toggle shuffle"); break;
+ case ACTION_TOGGLE_CROSSFADER: name = _(L"Toggle crossfader"); break;
+ }
+ return name;
+}
diff --git a/Src/Plugins/General/gen_ff/wa2coreactions.h b/Src/Plugins/General/gen_ff/wa2coreactions.h
new file mode 100644
index 00000000..eb405c48
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2coreactions.h
@@ -0,0 +1,6 @@
+#ifndef _WA2COREACTIONS_H
+#define _WA2COREACTIONS_H
+
+#include <api/core/coreactions.h>
+
+#endif
diff --git a/Src/Plugins/General/gen_ff/wa2frontend.cpp b/Src/Plugins/General/gen_ff/wa2frontend.cpp
new file mode 100644
index 00000000..d8ec944d
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2frontend.cpp
@@ -0,0 +1,1344 @@
+#include <precomp.h>
+/*------------------------------------------------------------------------------------------------
+ Winamp 2.9/5 frontend class
+------------------------------------------------------------------------------------------------*/
+#include <stdio.h>
+#include "main.h"
+#include "wa2frontend.h"
+#include "../winamp/wa_ipc.h"
+#include "../winamp/ipc_pe.h"
+#include "../gen_ml/ml.h"
+#include "../gen_ml/main.h"
+#include "../gen_hotkeys/wa_hotkeys.h"
+#include "../nu/AutoChar.h"
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+#define WINAMP_EDIT_ID3 40188
+
+
+Winamp2FrontEnd wa2;
+
+void Winamp2FrontEnd::init(HWND hwndParent)
+{
+ // find Winamp's HWND so we can talk to it
+ hwnd_winamp = hwndParent; //FindWindow("Winamp v1.x",NULL);
+
+ // check that hwnd_winamp isnt null and that we know about this specific ipc version
+ getVersion();
+
+ // more init
+ enabled = 1;
+ visible = 1;
+
+ *(void **)&export_sa_get=(void*)SendMessageW(hwnd_winamp,WM_WA_IPC,2,IPC_GETSADATAFUNC);
+ *(void **)&export_sa_setreq=(void *)SendMessageW(hwnd_winamp,WM_WA_IPC,1,IPC_GETSADATAFUNC);
+ *(void **)&export_sa_get_deprecated=(void*)SendMessageW(hwnd_winamp,WM_WA_IPC,0,IPC_GETSADATAFUNC);
+ *(void **)&export_vu_get=(void*)SendMessageW(hwnd_winamp,WM_WA_IPC,0,IPC_GETVUDATAFUNC);
+ if (reinterpret_cast<intptr_t>(export_vu_get) == -1)
+ export_vu_get=0;
+
+ hwnd_playlist = getWnd(IPC_GETWND_PE);
+}
+
+//-----------------------------------------------------------------------------------------------
+Winamp2FrontEnd::Winamp2FrontEnd()
+{
+ m_version = (char *)malloc(64);
+ *m_version = 0;
+ enabled = visible = foundvis =
+ saved_video =
+#ifdef MINIBROWSER_SUPPORT
+ saved_mb =
+#endif
+ saved_pe = saved_eq = saved_main = 0;
+
+ got_length_cache = 0;
+ cached_length = -1;
+ cached_length_time = 0;
+ got_pos_cache = 0;
+ cached_pos = -1;
+ cached_pos_time = 0;
+
+ video_ideal_height = -1;
+ video_ideal_width = -1;
+
+ hwnd_winamp = hwnd_playlist = NULL;
+
+ export_sa_get = 0;
+ export_sa_setreq = 0;
+ export_sa_get_deprecated = 0;
+ export_vu_get = 0;
+}
+
+//-----------------------------------------------------------------------------------------------
+Winamp2FrontEnd::~Winamp2FrontEnd()
+{
+ setWindowsVisible(1);
+ free(m_version);
+}
+
+//-----------------------------------------------------------------------------------------------
+const char *Winamp2FrontEnd::getVersion()
+{
+ if (hwnd_winamp == NULL)
+ {
+ char err[16] = {0};
+ MessageBoxA(NULL, WASABI_API_LNGSTRING(IDS_COULD_NOT_FIND_WINAMP),
+ WASABI_API_LNGSTRING_BUF(IDS_ERROR,err,16), 0);
+ m_version = "Winamp not found";
+ return m_version;
+ }
+
+ if (hwnd_winamp == NULL)
+ return NULL;
+
+ if (*m_version == 0)
+ {
+ // get version number
+ int version = SendMessageW(hwnd_winamp,WM_WA_IPC,0,IPC_GETVERSION);
+ // check that we support this version of the ipc
+ //assert(((version & 0xFF) >> 8) > 0x20);
+ // format the version number into a string
+ wsprintfA(m_version, "%d.%d%d", (version & 0xF000) >> 12, version & (0xF0 >> 4), version & 0xF);
+ }
+ return m_version;
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::userButton(int button, int modifier)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ int mod = 0;
+ switch (modifier)
+ {
+ case WA2_USERBUTTONMOD_NONE : break;
+ case WA2_USERBUTTONMOD_SHIFT: mod = 100; break;
+ case WA2_USERBUTTONMOD_CTRL : mod = 110; break;
+ }
+ switch (button)
+ {
+ case WA2_USERBUTTON_PREV: SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_BUTTON1 + mod,0); break;
+ case WA2_USERBUTTON_PLAY: SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_BUTTON2 + mod,0); break;
+ case WA2_USERBUTTON_PAUSE: SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_BUTTON3 + mod,0); break;
+ case WA2_USERBUTTON_STOP: SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_BUTTON4 + mod,0); break;
+ case WA2_USERBUTTON_NEXT: SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_BUTTON5 + mod,0); break;
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setOnTop(int ontop)
+{
+ if (!!ontop == !!isOnTop()) return;
+ toggleOnTop();
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::toggleOnTop()
+{
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_OPTIONS_AOT, 0);
+}
+
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::enqueueFile(const wchar_t *file)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ COPYDATASTRUCT cds;
+ cds.dwData = IPC_PLAYFILEW;
+ cds.lpData = (void *)file;
+ cds.cbData = sizeof(wchar_t) * (wcslen(file)+1);
+ SendMessageW(hwnd_winamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isPlaying()
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING) == 1;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isPaused()
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING) == 3;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isStopped()
+{
+ if (!IsWindow(hwnd_winamp)) return 1;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING) == 0;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getPosition()
+{
+ if ( !IsWindow( hwnd_winamp ) )
+ return 0;
+
+ if ( got_pos_cache && GetTickCount() < cached_pos_time + 20 )
+ return cached_pos;
+
+ got_pos_cache = 1;
+ cached_pos_time = GetTickCount();
+
+ return cached_pos = SendMessageW( hwnd_winamp, WM_WA_IPC, 0, IPC_GETOUTPUTTIME );
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getLength()
+{
+ if ( got_length_cache && GetTickCount() < cached_length_time + 3000 )
+ return cached_length;
+
+ if ( !IsWindow( hwnd_winamp ) )
+ return 0;
+
+ int l = SendMessageW( hwnd_winamp, WM_WA_IPC, 1, IPC_GETOUTPUTTIME );
+
+ if ( l == -1 )
+ cached_length = -1;
+ else
+ cached_length = l * 1000;
+
+ got_length_cache = 1;
+ cached_length_time = GetTickCount();
+
+ return cached_length;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::seekTo(int ms)
+{
+ got_pos_cache = 0;
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,ms,IPC_JUMPTOTIME);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setVolume(int v)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp,WM_WA_IPC,v,IPC_SETVOLUME);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getVolume()
+{
+ if (!IsWindow(hwnd_winamp)) return 255;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)-666,IPC_SETVOLUME);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setPanning(int p)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)p,IPC_SETPANNING);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getPanning()
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)-666,IPC_SETPANNING);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getInfo( int what )
+{
+ if ( !IsWindow( hwnd_winamp ) )
+ return 0;
+
+ return SendMessageW( hwnd_winamp, WM_WA_IPC, (WPARAM)what, IPC_GETINFO );
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getEqData(int what)
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)what,IPC_GETEQDATA);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setEqData(int what, int val)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ //SendMessageW(hwnd_winamp,WM_WA_IPC,what,IPC_GETEQDATA); // f this :)
+ SendMessageW(hwnd_winamp,WM_WA_IPC,0xDB000000 | ((what&0xFF) << 16) | (val&0xFFFF),IPC_SETEQDATA);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getShuffle()
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GET_SHUFFLE);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getRepeat()
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GET_REPEAT);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setShuffle(int shuffle)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)shuffle,IPC_SET_SHUFFLE);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setRepeat(int repeat)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)repeat,IPC_SET_REPEAT);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setManualPlaylistAdvance(int manual)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)manual,IPC_SET_MANUALPLADVANCE);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getManualPlaylistAdvance()
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GET_MANUALPLADVANCE);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::enableWindows( int enabled )
+{
+ if ( !IsWindow( hwnd_winamp ) )
+ return;
+
+ SendMessageW( hwnd_winamp, WM_WA_IPC, enabled ? 0 : 0xdeadbeef, IPC_ENABLEDISABLE_ALL_WINDOWS );
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::areWindowsEnabled()
+{
+ if ( !IsWindow( hwnd_winamp ) )
+ return 1;
+
+ return 1; // todo !!
+}
+
+//-----------------------------------------------------------------------------------------------
+int _IsWindowVisible( HWND w )
+{
+ if ( !IsWindowVisible( w ) )
+ return 0;
+
+ RECT r;
+ GetWindowRect( w, &r );
+
+ return !( r.left >= 3000 && r.top >= 3000 );
+}
+
+int Winamp2FrontEnd::isMainWindowVisible()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)0, IPC_ISMAINWNDVISIBLE);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setWindowsVisible(int v)
+{
+ if (visible == v)
+ return;
+
+ if (!IsWindow(hwnd_winamp))
+ return;
+
+ if (v)
+ {
+ if (saved_main && ! isMainWindowVisible())
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_MAIN_WINDOW, 0);
+ if (saved_eq && !isWindowVisible(IPC_GETWND_EQ))
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_OPTIONS_EQ, 0);
+#ifdef MINIBROWSER_SUPPORT
+ if (saved_mb && !isWindowVisible(IPC_GETWND_MB))
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_OPTIONS_MINIBROWSER, 0);
+#endif
+ if (saved_pe && !isWindowVisible(IPC_GETWND_PE))
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_OPTIONS_PLEDIT, 0);
+ if (saved_video && !isWindowVisible(IPC_GETWND_VIDEO))
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_OPTIONS_VIDEO, 0);
+ }
+ else
+ {
+ if (isMainWindowVisible())
+ {
+ saved_main = 1;
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_MAIN_WINDOW, 0);
+ }
+ else
+ saved_main = 0;
+
+ if (isWindowVisible(IPC_GETWND_EQ))
+ {
+ saved_eq = 1;
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_OPTIONS_EQ, 0);
+ }
+ else
+ saved_eq = 0;
+
+#ifdef MINIBROWSER_SUPPORT
+ if (isWindowVisible(IPC_GETWND_MB))
+ {
+ saved_mb = 1;
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_OPTIONS_MINIBROWSER, 0);
+ }
+ else saved_mb = 0;
+#endif
+ if (isWindowVisible(IPC_GETWND_PE))
+ {
+ saved_pe = 1;
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_OPTIONS_PLEDIT, 0);
+ }
+ else
+ saved_pe = 0;
+
+ if (isWindowVisible(IPC_GETWND_VIDEO))
+ {
+ saved_video = 1;
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_OPTIONS_VIDEO, 0);
+ }
+ else saved_video = 0;
+ }
+ visible = v;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::areWindowsVisible()
+{
+ if (!IsWindow(hwnd_winamp))
+ return 1;
+
+ return visible;
+}
+
+//-----------------------------------------------------------------------------------------------
+HWND Winamp2FrontEnd::getWnd(int wnd)
+{
+ if (!IsWindow(hwnd_winamp))
+ return NULL;
+
+ return (HWND)SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)wnd,IPC_GETWND);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getPlaylistLength()
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GETLISTLENGTH);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getCurPlaylistEntry()
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GETLISTPOS);
+}
+
+//-----------------------------------------------------------------------------------------------
+const wchar_t *Winamp2FrontEnd::getTitle(int plentry)
+{
+ if (!IsWindow(hwnd_winamp)) return NULL;
+ return (const wchar_t *)SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)plentry,IPC_GETPLAYLISTTITLEW);
+}
+
+//-----------------------------------------------------------------------------------------------
+const char *Winamp2FrontEnd::getFile(int plentry)
+{
+ if (!IsWindow(hwnd_winamp)) return NULL;
+ return (const char *)SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)plentry,IPC_GETPLAYLISTFILE);
+}
+
+const wchar_t *Winamp2FrontEnd::getFileW(int plentry)
+{
+ if (!IsWindow(hwnd_winamp)) return NULL;
+ return (const wchar_t *)SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)plentry,IPC_GETPLAYLISTFILEW);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::playAudioCD(int cd)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp,WM_COMMAND,ID_MAIN_PLAY_AUDIOCD1+cd,0);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::openFileDialog(HWND w)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)w, IPC_OPENFILEBOX);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::openUrlDialog(HWND w)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_BUTTON2_CTRL, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::openDirectoryDialog(HWND w)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)w, IPC_OPENDIRBOX);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::ejectPopupMenu()
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)0, IPC_SPAWNBUTTONPOPUP);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::previousPopupMenu()
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)1, IPC_SPAWNBUTTONPOPUP);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::nextPopupMenu()
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)2, IPC_SPAWNBUTTONPOPUP);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::pausePopupMenu()
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)3, IPC_SPAWNBUTTONPOPUP);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::playPopupMenu()
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)4, IPC_SPAWNBUTTONPOPUP);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::stopPopupMenu()
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)5, IPC_SPAWNBUTTONPOPUP);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setDialogBoxParent(HWND w)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)w, IPC_SETDIALOGBOXPARENT);
+}
+
+void Winamp2FrontEnd::updateDialogBoxParent(HWND w)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)w, IPC_UPDATEDIALOGBOXPARENT);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isOnTop()
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_IS_AOT);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::triggerPopupMenu(int x, int y)
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ HMENU hMenu = (HMENU)SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GET_HMENU);
+ DoTrackPopup(hMenu, TPM_RIGHTBUTTON, x, y, hwnd_winamp);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::triggerEQPresetMenu(int x, int y)
+{
+ waSpawnMenuParms p = {hwnd_winamp, x, y};
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNEQPRESETMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerFileMenu(int x, int y, int width, int height)
+{
+ waSpawnMenuParms2 p = {hwnd_winamp, x, y, width, height};
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNFILEMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerPlayMenu(int x, int y, int width, int height)
+{
+ waSpawnMenuParms2 p = {hwnd_winamp, x, y, width, height};
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNPLAYMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerOptionsMenu(int x, int y, int width, int height)
+{
+ waSpawnMenuParms2 p = {hwnd_winamp, x, y, width, height};
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNOPTIONSMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerWindowsMenu(int x, int y, int width, int height)
+{
+ waSpawnMenuParms2 p = {hwnd_winamp, x, y, width, height};
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNWINDOWSMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerHelpMenu(int x, int y, int width, int height)
+{
+ waSpawnMenuParms2 p = {hwnd_winamp, x, y, width, height};
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNHELPMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerPEFileMenu(int x, int y, int width, int height)
+{
+ int IPC_GETMLWINDOW=SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)&"LibraryGetWnd",IPC_REGISTER_WINAMP_IPCMESSAGE);
+ if (IPC_GETMLWINDOW > 65536) SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)-1, IPC_GETMLWINDOW);
+ waSpawnMenuParms2 p = {hwnd_winamp, x, y, width, height};
+ p.wnd = getWnd(IPC_GETWND_PE);
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNPEFILEMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerPEPlaylistMenu(int x, int y, int width, int height)
+{
+ waSpawnMenuParms2 p = {hwnd_winamp, x, y, width, height};
+ p.wnd = getWnd(IPC_GETWND_PE);
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNPEPLAYLISTMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerPESortMenu(int x, int y, int width, int height)
+{
+ waSpawnMenuParms2 p = {hwnd_winamp, x, y, width, height};
+ p.wnd = getWnd(IPC_GETWND_PE);
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNPESORTMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerPEHelpMenu(int x, int y, int width, int height)
+{
+ waSpawnMenuParms2 p = {hwnd_winamp, x, y, width, height};
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNPEHELPMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerPEListOfListsMenu(int x, int y)
+{
+ int IPC_GETMLWINDOW=SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)&"LibraryGetWnd",IPC_REGISTER_WINAMP_IPCMESSAGE);
+ if (IPC_GETMLWINDOW > 65536) SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)-1, IPC_GETMLWINDOW);
+ waSpawnMenuParms p = {hwnd_winamp, x, y};
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNPELISTOFPLAYLISTS);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerMLFileMenu(int x, int y, int width, int height)
+{
+ waSpawnMenuParms2 p = {hwnd_winamp, x, y, width, height};
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNMLFILEMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerMLViewMenu(int x, int y, int width, int height)
+{
+ waSpawnMenuParms2 p = {hwnd_winamp, x, y, width, height};
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNMLVIEWMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::triggerMLHelpMenu(int x, int y, int width, int height)
+{
+ waSpawnMenuParms2 p = {hwnd_winamp, x, y, width, height};
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&p, IPC_SPAWNMLHELPMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+HMENU Winamp2FrontEnd::getPopupMenu()
+{
+ if (!IsWindow(hwnd_winamp)) return NULL;
+ return (HMENU)SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GET_HMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+HMENU Winamp2FrontEnd::getTopMenu()
+{
+ if (!IsWindow(hwnd_winamp)) return NULL;
+ return (HMENU)SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)-1,IPC_GET_HMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::adjustOptionsPopupMenu(int direction)
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)direction,IPC_ADJUST_OPTIONSMENUPOS);
+}
+
+//-----------------------------------------------------------------------------------------------
+HMENU Winamp2FrontEnd::getMenuBarMenu(int which)
+{
+ if (!IsWindow(hwnd_winamp)) return NULL;
+ return (HMENU)SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)which+1,IPC_GET_HMENU);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::adjustFFWindowsMenu(int direction)
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)direction,IPC_ADJUST_FFWINDOWSMENUPOS);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::adjustFFOptionsMenu(int direction)
+{
+ if (!IsWindow(hwnd_winamp)) return 0;
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)direction,IPC_ADJUST_FFOPTIONSMENUPOS);
+}
+
+//-----------------------------------------------------------------------------------------------
+HWND Winamp2FrontEnd::getMainWindow()
+{
+ return hwnd_winamp;
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::quit()
+{
+ if (!IsWindow(hwnd_winamp)) return;
+ SendMessageW(hwnd_winamp,WM_CLOSE,0,0);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isWindowVisible(intptr_t which)
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, which, IPC_ISWNDVISIBLE);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setWindowVisible(intptr_t which, int visible)
+{
+ int state = isWindowVisible(which);
+ if (!state == !visible) return;
+ int id = 0;
+ switch (which)
+ {
+ case IPC_GETWND_EQ:
+ DebugStringW(L"Showing EQ!!\n");
+ id = WINAMP_OPTIONS_EQ;
+ break;
+ case IPC_GETWND_PE:
+ id = WINAMP_OPTIONS_PLEDIT;
+ break;
+#ifdef MINIBROWSER_SUPPORT
+ case IPC_GETWND_MB:
+ id = WINAMP_OPTIONS_MINIBROWSER;
+ break;
+#endif
+ case IPC_GETWND_VIDEO:
+ id = WINAMP_OPTIONS_VIDEO;
+ break;
+ }
+ SendMessageW(hwnd_winamp, WM_COMMAND, id, 0);
+}
+
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::sendPlCmd(int which, int x, int y, int menu_align_flag)
+{
+ windowCommand wc = {which, x, y, menu_align_flag};
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (intptr_t)&wc, IPC_PLCMD);
+}
+
+#ifdef MINIBROWSER_SUPPORT
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::sendMbCmd(int which, int x, int y, int menu_align_flag)
+{
+ windowCommand wc = {which, x, y, menu_align_flag};
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (intptr_t)&wc, IPC_MBCMD);
+}
+#endif
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::sendVidCmd(int which, int x, int y, int menu_align_flag)
+{
+ windowCommand wc = {which, x, y, menu_align_flag};
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (intptr_t)&wc, IPC_VIDCMD);
+}
+
+
+//-----------------------------------------------------------------------------------------------
+#define WINAMP_VISPLUGIN 40192
+void Winamp2FrontEnd::toggleVis()
+{
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_VISPLUGIN, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isVisRunning()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_ISVISRUNNING);
+}
+
+//-----------------------------------------------------------------------------------------------
+HWND Winamp2FrontEnd::getVisWnd()
+{
+ return (HWND)SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GETVISWND);
+}
+
+//-----------------------------------------------------------------------------------------------
+IDropTarget *Winamp2FrontEnd::getDropTarget()
+{
+ return (IDropTarget *)SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GETDROPTARGET);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getSamplerate()
+{
+ int realRate = SendMessageW(hwnd_winamp,WM_WA_IPC,5,IPC_GETINFO);
+ if (realRate == 1)
+ return 1000*SendMessageW(hwnd_winamp,WM_WA_IPC,0,IPC_GETINFO);
+ else
+ return realRate;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getBitrate()
+{
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,1,IPC_GETINFO);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getChannels()
+{
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,2,IPC_GETINFO);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isValidEmbedWndState(embedWindowState *ws)
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, (intptr_t)ws, IPC_EMBED_ISVALID);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::PE_getNumItems()
+{
+ return SendMessageW(hwnd_playlist, WM_USER, IPC_PE_GETINDEXTOTAL, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+fileinfo2 *Winamp2FrontEnd::PE_getFileTitle(int index)
+{
+ static fileinfo2 fi;
+ fi.fileindex = index;
+ *(fi.filetitle) = 0;
+ *(fi.filelength) = 0;
+ SendMessageW(hwnd_playlist, WM_USER, IPC_PE_GETINDEXTITLE, (LPARAM)&fi);
+ return &fi;
+}
+
+//-----------------------------------------------------------------------------------------------
+fileinfo2W *Winamp2FrontEnd::PE_getFileTitleW(int index)
+{
+ static fileinfo2W fi;
+ fi.fileindex = index;
+ *(fi.filetitle) = 0;
+ *(fi.filelength) = 0;
+ SendMessageW(hwnd_playlist, WM_USER, IPC_PE_GETINDEXTITLEW, (LPARAM)&fi);
+ return &fi;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::PE_getCurrentIndex()
+{
+ //return SendMessageW(hwnd_playlist, WM_USER, IPC_PE_GETCURINDEX, 0);
+ return SendMessageW(hwnd_winamp, WM_USER, 0, IPC_GETLISTPOS);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::PE_setCurrentIndex(int i)
+{
+ SendMessageW(hwnd_winamp, WM_WA_IPC, i, IPC_SETPLAYLISTPOS);
+}
+
+//-----------------------------------------------------------------------------------------------
+HWND Winamp2FrontEnd::getMediaLibrary()
+{
+ int IPC_GETMLWINDOW=SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)&"LibraryGetWnd",IPC_REGISTER_WINAMP_IPCMESSAGE);
+ return IPC_GETMLWINDOW > 65536 ? (HWND)SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GETMLWINDOW) : NULL;
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::ensureMediaLibraryLoaded()
+{
+ int IPC_GETMLWINDOW=SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)&"LibraryGetWnd",IPC_REGISTER_WINAMP_IPCMESSAGE);
+ if (IPC_GETMLWINDOW > 65536) SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)-1, IPC_GETMLWINDOW);
+}
+
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::hasVideoSupport()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_HAS_VIDEO_SUPPORT);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isPlayingVideo()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_IS_PLAYING_VIDEO) > 0;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isPlayingVideoFullscreen()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_IS_FULLSCREEN);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isDoubleSize()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_ISDOUBLESIZE);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getTimeDisplayMode()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GETTIMEDISPLAYMODE);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::switchSkin(const wchar_t *skinname)
+{
+ static StringW wideSkinName;
+ wideSkinName=skinname;
+ PostMessage(hwnd_winamp, WM_WA_IPC, (intptr_t)wideSkinName.getValue(), IPC_SETSKINW);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::visNext()
+{
+ PostMessage(hwnd_winamp, WM_COMMAND, ID_VIS_NEXT, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::visFullscreen()
+{
+ PostMessage(hwnd_winamp, WM_COMMAND, ID_VIS_FS, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::visPrev()
+{
+ PostMessage(hwnd_winamp, WM_COMMAND, ID_VIS_PREV, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::visRandom(int set)
+{
+ PostMessage(hwnd_winamp, WM_COMMAND, ID_VIS_RANDOM | (set << 16), 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::pollVisRandom()
+{
+ PostMessage(hwnd_winamp, WM_COMMAND, ID_VIS_RANDOM | 0xFFFF0000, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::visConfig()
+{
+ PostMessage(hwnd_winamp, WM_COMMAND, ID_VIS_CFG, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::visMenu()
+{
+ PostMessage(hwnd_winamp, WM_COMMAND, ID_VIS_MENU, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::getIdealVideoSize(int *w, int *h)
+{
+ if (w) *w = video_ideal_width;
+ if (h) *h = video_ideal_height;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getStopOnVideoClose()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GETSTOPONVIDEOCLOSE);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setStopOnVideoClose(int stop)
+{
+ SendMessageW(hwnd_winamp, WM_WA_IPC, stop, IPC_SETSTOPONVIDEOCLOSE);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::GetVideoResize()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GETVIDEORESIZE);
+}
+
+
+void Winamp2FrontEnd::SetVideoResize(int stop)
+{
+ SendMessageW(hwnd_winamp, WM_WA_IPC, stop, IPC_SETVIDEORESIZE);
+}
+
+
+//-----------------------------------------------------------------------------------------------
+BOOL CALLBACK findVisWndProc(HWND hwnd, LPARAM lParam)
+{
+ Winamp2FrontEnd *fe = (Winamp2FrontEnd*)lParam;
+ if (hwnd == fe->getVisWnd())
+ {
+ fe->setFoundVis(); return FALSE;
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isVis(HWND hwnd)
+{
+ if (hwnd == wa2.getVisWnd()) return 1;
+ foundvis = 0;
+ EnumChildWindows(hwnd, findVisWndProc, (LPARAM)this);
+ return foundvis;
+}
+
+//-----------------------------------------------------------------------------------------------
+HWND Winamp2FrontEnd::getPreferencesWindow()
+{
+ return (HWND)SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GETPREFSWND);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setPlEditWidthHeight(int width, int height)
+{
+ POINT pt={width, height};
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&pt, IPC_SET_PE_WIDTHHEIGHT);
+}
+
+//-----------------------------------------------------------------------------------------------
+HINSTANCE Winamp2FrontEnd::getLanguagePackInstance()
+{
+ return (HINSTANCE)SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GETLANGUAGEPACKINSTANCE);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::openTrackInfo()
+{
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_EDIT_ID3, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+const char *Winamp2FrontEnd::getOutputPlugin()
+{
+ return (const char *)SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GETOUTPUTPLUGIN);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::setDrawBorders(int d)
+{
+ SendMessageW(hwnd_winamp, WM_WA_IPC, d, IPC_SETDRAWBORDERS);
+}
+
+//-----------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::disableSkinnedCursors(int disable)
+{
+ SendMessageW(hwnd_winamp, WM_WA_IPC, disable, IPC_DISABLESKINCURSORS);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getMetaData(const wchar_t *filename, const wchar_t *name, wchar_t *data, int data_len)
+{
+
+ if (!_wcsnicmp(filename, L"file://", 7))
+ filename+=7;
+ extendedFileInfoStructW efis=
+ {
+ filename,
+ name,
+ data,
+ data_len,
+ };
+ return SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)&efis,IPC_GET_EXTENDED_FILE_INFOW_HOOKABLE);
+}
+//------------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::invalidateCache()
+{
+ got_length_cache = 0;
+ got_pos_cache = 0;
+}
+
+//------------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::registerGlobalHotkey(const char *name, int msg, int wparam, int lparam, int flags, const char *id)
+{
+ int m_genhotkeys_add_ipc=SendMessageW(hwnd_winamp,WM_WA_IPC,(WPARAM)&"GenHotkeysAdd",IPC_REGISTER_WINAMP_IPCMESSAGE);
+ genHotkeysAddStruct hs={0,};
+ hs.name = (char *)name;
+ hs.uMsg = msg;
+ hs.wParam = wparam;
+ hs.lParam = lparam;
+ hs.flags = flags;
+ hs.id = (char *)id;
+ if (m_genhotkeys_add_ipc > 65536) SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&hs, m_genhotkeys_add_ipc);
+}
+
+//------------------------------------------------------------------------------------------------
+const char *Winamp2FrontEnd::getVideoInfoString()
+{
+ return (const char *)SendMessageW(hwnd_winamp, WM_WA_IPC, 4, IPC_GETINFO);
+}
+
+//------------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::playFile(const wchar_t *file)
+{
+ SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_DELETE);
+ COPYDATASTRUCT cds;
+ cds.dwData = IPC_PLAYFILEW;
+ cds.lpData = (void *)file;
+ cds.cbData = sizeof(wchar_t) * (wcslen(file)+1); // +1 to get the NULL, missing forever
+ SendMessageW(hwnd_winamp, WM_COPYDATA, (WPARAM)hwnd_winamp, (LPARAM)&cds);
+ SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_STARTPLAY);
+}
+
+void Winamp2FrontEnd::clearPlaylist()
+{
+ SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_DELETE);
+}
+
+//------------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::rewind5s()
+{
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_REW5S, 0);
+}
+
+//------------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::forward5s()
+{
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_FFWD5S, 0);
+}
+
+//------------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::endOfPlaylist()
+{
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_BUTTON5_CTRL, 0);
+}
+
+//------------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::startOfPlaylist()
+{
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_BUTTON1_CTRL, 0);
+}
+
+//------------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::stopWithFade()
+{
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_BUTTON4_SHIFT, 0);
+}
+
+//------------------------------------------------------------------------------------------------
+void Winamp2FrontEnd::stopAfterCurrent()
+{
+ SendMessageW(hwnd_winamp, WM_COMMAND, WINAMP_BUTTON4_CTRL, 0);
+}
+
+//------------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isWindowShade(int whichwnd)
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, whichwnd, IPC_IS_WNDSHADE);
+}
+
+//------------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::getCurTrackRating()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GETRATING);
+}
+
+void Winamp2FrontEnd::setCurTrackRating(int rating)
+{
+ SendMessageW(hwnd_winamp, WM_WA_IPC, rating, IPC_SETRATING);
+}
+
+//------------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::isExitEnabled()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_IS_EXIT_ENABLED);
+}
+
+//------------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::pushExitDisabled()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_PUSH_DISABLE_EXIT);
+}
+
+//------------------------------------------------------------------------------------------------
+int Winamp2FrontEnd::popExitDisabled()
+{
+ return SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_POP_DISABLE_EXIT);
+}
+
+void Winamp2FrontEnd::GetFileInfo(const wchar_t *filename, wchar_t *title, int titleCch, int *length)
+{
+ basicFileInfoStructW infoStruct = {0};
+ infoStruct.filename = filename;
+ infoStruct.title = title;
+ infoStruct.titlelen = titleCch;
+ SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&infoStruct, IPC_GET_BASIC_FILE_INFOW);
+ *length = infoStruct.length;
+}
+
+const wchar_t *Winamp2FrontEnd::GetCurrentTitle()
+{
+ return (const wchar_t *)SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GET_PLAYING_TITLE);
+}
+
+const wchar_t *Winamp2FrontEnd::GetCurrentFile()
+{
+ return (const wchar_t *)SendMessageW(hwnd_winamp, WM_WA_IPC, 0, IPC_GET_PLAYING_FILENAME);
+}
+
+void *Winamp2FrontEnd::CanPlay(const wchar_t *fn)
+{
+ return (void *)SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)fn, IPC_CANPLAY);
+}
+
+bool Winamp2FrontEnd::IsPlaylist(const wchar_t *fn)
+{
+ return AGAVE_API_PLAYLISTMANAGER->CanLoad(fn);
+}
+
+
+
+HWND GetMainContainerHWND();
+bool Winamp2FrontEnd::GetAlbumArt(const wchar_t *filename)
+{
+ // disabled 30 May 2012 as per email from Tejas w.r.t. to Rovi deal ending
+ #if 0
+ if (!_wcsnicmp(filename, L"file://", 7))
+ filename+=7;
+
+ artFetchData fetch = {sizeof(artFetchData), GetMainContainerHWND(), };
+
+
+
+ wchar_t artist[512]=L"", album[512]=L"", gracenoteFileId[512]=L"", year[5]=L"";
+ getMetaData(filename, L"albumartist", artist, 512);
+ if (!WCSICMP(artist, L"")) //Add artist if albumartist not available
+ getMetaData(filename, L"artist", artist, 512);
+ getMetaData(filename, L"album", album, 512);
+ getMetaData(filename, L"GracenoteFileID", gracenoteFileId, 512);
+ getMetaData(filename, L"year", year, 5);
+
+ fetch.artist=artist;
+ fetch.album=album;
+ fetch.gracenoteFileId=gracenoteFileId;
+ fetch.year=_wtoi(year);
+
+ int r = SendMessageW(hwnd_winamp, WM_WA_IPC, (WPARAM)&fetch, IPC_FETCH_ALBUMART);
+ if(r == 0 && fetch.imgData && fetch.imgDataLen) // success, save art in correct location
+ {
+ AGAVE_API_ALBUMART->SetAlbumArt(filename,L"cover",0,0,fetch.imgData,fetch.imgDataLen,fetch.type);
+ WASABI_API_MEMMGR->sysFree(fetch.imgData);
+ return true;
+ }
+ #endif
+ return false;
+}
+
+static void code(long* v, long* k)
+{
+ unsigned long y = v[0], z = v[1], sum = 0, /* set up */
+ delta = 0x9e3779b9, n = 32 ; /* key schedule constant*/
+
+ while (n-- > 0)
+ { /* basic cycle start */
+ sum += delta;
+ y += ((z << 4) + k[0]) ^(z + sum) ^((z >> 5) + k[1]);
+ z += ((y << 4) + k[2]) ^(y + sum) ^((y >> 5) + k[3]); /* end cycle */
+ }
+ v[0] = y; v[1] = z;
+
+}
+
+static int getRegVer()
+{
+ int *x = (int*)malloc(32);
+ long s[3];
+ long ss[2] = {GetTickCount(), (int)x + (int)s}; // fucko: better challenge, too
+ long tealike_key[4] = { 31337, 0xf00d, 0xdead, 0xbeef}; //fucko: hide this a bit
+ free(x);
+ s[0] = ss[0];
+ s[1] = ss[1];
+ s[2] = 0;
+
+ SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)s, IPC_GETREGISTEREDVERSION);
+
+ code(ss, tealike_key);
+
+ if (memcmp(s, ss, 8)) return 0;
+
+ return s[2];
+}
+
+bool Winamp2FrontEnd::IsWinampPro()
+{
+ return !!getRegVer();
+}
+
+void Winamp2FrontEnd::openUrl(const wchar_t *url)
+{
+ SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)url, IPC_OPEN_URL);
+}
+
+#include "../gen_ml/menu.h"
+
+LRESULT sendMlIpc(int msg, WPARAM param)
+{
+ static LRESULT IPC_GETMLWINDOW;
+ if (!IPC_GETMLWINDOW) IPC_GETMLWINDOW = SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)&"LibraryGetWnd", IPC_REGISTER_WINAMP_IPCMESSAGE);
+ HWND mlwnd = (HWND)SendMessageW(plugin.hwndParent, WM_WA_IPC, 0, IPC_GETMLWINDOW);
+
+ if (param == 0 && msg == 0) return (LRESULT)mlwnd;
+
+ if (IsWindow(mlwnd))
+ return SendMessageW(mlwnd, WM_ML_IPC, param, msg);
+
+ return 0;
+}
+
+BOOL DoTrackPopup(HMENU hMenu, UINT fuFlags, int x, int y, HWND hwnd)
+{
+ if(hMenu == NULL)
+ {
+ return NULL;
+ }
+
+ HWND ml_wnd = (HWND)sendMlIpc(0, 0);
+ if (IsWindow(ml_wnd))
+ {
+ return Menu_TrackPopup(ml_wnd, hMenu, fuFlags, x, y, hwnd, NULL);
+ }
+ else
+ {
+ return TrackPopupMenu(hMenu, fuFlags, x, y, 0, hwnd, NULL);
+ }
+} \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/wa2frontend.h b/Src/Plugins/General/gen_ff/wa2frontend.h
new file mode 100644
index 00000000..38eb819b
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2frontend.h
@@ -0,0 +1,359 @@
+#ifndef __WINAMP2FRONTEND_H
+#define __WINAMP2FRONTEND_H
+
+#define WA2_GETINFO_SAMPLERATE 0
+#define WA2_GETINFO_BITRATE 1
+#define WA2_GETINFO_CHANNELS 2
+
+#define WA2_NUMBANDS 10
+
+#define WA2_EQDATA_FIRSTBAND 0
+#define WA2_EQDATA_LASTBAND 9
+#define WA2_EQDATA_PREAMP 10
+#define WA2_EQDATA_ENABLED 11
+#define WA2_EQDATA_AUTO 12
+
+#define IPC_GETWND_EQ 0
+#define IPC_GETWND_PE 1
+#define IPC_GETWND_MB 2
+#define IPC_GETWND_VIDEO 3
+
+#define WA2_USERBUTTON_PREV 0
+#define WA2_USERBUTTON_PLAY 1
+#define WA2_USERBUTTON_PAUSE 2
+#define WA2_USERBUTTON_STOP 3
+#define WA2_USERBUTTON_NEXT 4
+
+#define WA2_USERBUTTONMOD_NONE 0
+#define WA2_USERBUTTONMOD_SHIFT 1
+#define WA2_USERBUTTONMOD_CTRL 2
+
+#define WINAMP_MAIN_WINDOW 40258
+#define WINAMP_OPTIONS_MINIBROWSER 40298
+#define WINAMP_OPTIONS_VIDEO 40328
+#define WINAMP_OPTIONS_PLEDIT 40040
+#define WINAMP_OPTIONS_EQ 40036
+
+#define WINAMP_FILE_LOC 40185
+#define WINAMP_FILE_PLAY 40029
+#define WINAMP_FILE_DIR 40187
+
+//-----------------------------------------------------------------------------------------------
+
+#include <windows.h>
+#include "../gen_ml/ml.h"
+#include "../winamp/wa_ipc.h"
+#include "../winamp/ipc_pe.h"
+
+//-----------------------------------------------------------------------------------------------
+
+class Winamp2FrontEnd {
+ public:
+ friend BOOL CALLBACK findVisWndProc(HWND hwnd, LPARAM lParam);
+ Winamp2FrontEnd();
+ virtual ~Winamp2FrontEnd();
+
+ void init(HWND hwndParent);
+
+ const char *getVersion();
+
+ void enqueueFile(const wchar_t *file);
+
+ /*
+ WA2_USERBUTTON_PLAY
+ WA2_USERBUTTON_PAUSE
+ WA2_USERBUTTON_STOP
+ WA2_USERBUTTON_NEXT
+ WA2_USERBUTTON_PREV
+
+ WA2_USERBUTTONMOD_SHIFT
+ WA2_USERBUTTONMOD_CTRL
+ */
+ void userButton(int button, int modifier);
+
+ int isPlaying(); // 0 (false) or 1 (true)
+ int isPaused(); // 0 (false) or 1 (true)
+ int isStopped(); // if !isPlaying() and !isStopped() and !isPaused(), we're between tracks
+
+ int getPosition(); // in ms
+ int getLength(); // in ms
+ int seekTo(int ms); // in millisecond
+
+ void setVolume(int v); // 0 (silence) to 255 (loud)
+ int getVolume(); // 0 (silence) to 255 (loud)
+
+ void setPanning(int p); // 0 (left) to 255 (right)
+ int getPanning(); // 0 (left) to 255 (right)
+
+ void setShuffle(int shuffle);
+ int getShuffle();
+
+ void setRepeat(int repeat);
+ int getRepeat();
+
+ void setManualPlaylistAdvance(int manual);
+ int getManualPlaylistAdvance();
+
+ /*
+ WA2_GETINFO_SAMPLERATE : Samplerate (i.e. 44100)
+ WA2_GETINFO_BITRATE : Bitrate (i.e. 128)
+ WA2_GETINFO_CHANNELS : Channels (i.e. 2)
+ */
+ int getInfo(int wa2_getinfo);
+
+ /*
+ WA2_EQDATA_FIRSTBAND/LASTBAND (0 to 9) : The 10 bands of EQ data. 0-63 (+20db - -20db)
+ WA2_EQDATA_PREAMP : The preamp value. 0-63 (+20db - -20db)
+ WA2_EQDATA_ENABLED : Enabled. zero if disabled, nonzero if enabled.
+ WA2_EQDATA_AUTO : Autoload. zero if disabled, nonzero if enabled.
+ */
+ int getEqData(int wa2_eqdata);
+ void setEqData(int wa2_eqdata, int val);
+
+ void enableWindows(int enabled);
+ int areWindowsEnabled();
+ void setWindowsVisible(int visible);
+ int areWindowsVisible();
+ int isMainWindowVisible();
+
+ void *CanPlay(const wchar_t *);
+ bool IsPlaylist(const wchar_t *fn);
+ int getCurPlaylistEntry();
+ int getPlaylistLength();
+
+ const wchar_t *GetCurrentTitle();
+ const wchar_t *GetCurrentFile();
+ const wchar_t *getTitle(int plentry);
+ const char *getFile(int plentry);
+ const wchar_t *getFileW(int plentry);
+
+ void setCurTitle(const wchar_t* new_title);
+
+ void playAudioCD(int cd); // id of cd (0 to 4)
+
+ void openFileDialog(HWND w);
+ void openUrlDialog(HWND w);
+ void openUrl(const wchar_t *url);
+ void openDirectoryDialog(HWND w);
+ void ejectPopupMenu();
+ void previousPopupMenu();
+ void nextPopupMenu();
+ void playPopupMenu();
+ void pausePopupMenu();
+ void stopPopupMenu();
+ void setDialogBoxParent(HWND w);
+ void updateDialogBoxParent(HWND w);
+
+ /*
+ IPC_GETWND_EQ
+ IPC_GETWND_PE
+ IPC_GETWND_MB
+ IPC_GETWND_VIDEO
+ */
+ HWND getWnd(int wnd);
+ int isWindowVisible(intptr_t which);
+ void setWindowVisible(intptr_t which, int visible);
+ HWND getMediaLibrary();
+ void ensureMediaLibraryLoaded();
+
+ int isOnTop();
+ void setOnTop(int ontop);
+ void toggleOnTop();
+
+ // screen coordinates
+ void triggerPopupMenu(int x, int y);
+ void triggerEQPresetMenu(int x, int y);
+ int triggerFileMenu(int x, int y, int width, int height);
+ int triggerPlayMenu(int x, int y, int width, int height);
+ int triggerOptionsMenu(int x, int y, int width, int height);
+ int triggerWindowsMenu(int x, int y, int width, int height);
+ int triggerHelpMenu(int x, int y, int width, int height);
+ int triggerPEFileMenu(int x, int y, int width, int height);
+ int triggerPEPlaylistMenu(int x, int y, int width, int height);
+ int triggerPESortMenu(int x, int y, int width, int height);
+ int triggerPEHelpMenu(int x, int y, int width, int height);
+ int triggerMLFileMenu(int x, int y, int width, int height);
+ int triggerMLViewMenu(int x, int y, int width, int height);
+ int triggerMLHelpMenu(int x, int y, int width, int height);
+ int triggerPEListOfListsMenu(int x, int y);
+
+ HMENU getTopMenu();
+ HMENU getPopupMenu();
+ int adjustOptionsPopupMenu(int direction);
+
+ enum {
+ WA2_MAINMENUBAR_FILE = 0,
+ WA2_MAINMENUBAR_PLAY = 1,
+ WA2_MAINMENUBAR_OPTIONS = 2,
+ WA2_MAINMENUBAR_WINDOWS = 3,
+ WA2_MAINUMENUBAR_HELP = 4,
+ };
+
+ HMENU getMenuBarMenu(int which);
+ int adjustFFWindowsMenu(int direction);
+ int adjustFFOptionsMenu(int direction);
+
+ HWND getMainWindow();
+
+ void quit();
+
+ char * (*export_sa_get_deprecated)();
+ char * (*export_sa_get)(char data[75*2+8]);
+ void (*export_sa_setreq)(int);
+ int (*export_vu_get)(int channel);
+
+ enum {
+ WA2_PLEDITPOPUP_ADD = 0,
+ WA2_PLEDITPOPUP_REM = 1,
+ WA2_PLEDITPOPUP_SEL = 2,
+ WA2_PLEDITPOPUP_MISC = 3,
+ WA2_PLEDITPOPUP_LIST = 4,
+ };
+
+ void sendPlCmd(int which, int x=0, int y=0, int menu_align_flag=0);
+
+ enum {
+ WA2_MBCMD_BACK = 0,
+ WA2_MBCMD_FORWARD = 1,
+ WA2_MBCMD_STOP = 2,
+ WA2_MBCMD_RELOAD = 3,
+ WA2_MBPOPUP_MISC = 4,
+ };
+
+ void registerGlobalHotkey(const char *name, int msg, int wparam, int lparam, int flags, const char *id);
+
+#ifdef MINIBROWSER_SUPPORT
+ void sendMbCmd(int which, int x=0, int y=0, int menu_align_flag=0);
+#endif
+
+ enum {
+ WA2_VIDCMD_FULLSCREEN = 0,
+ WA2_VIDCMD_1X = 1,
+ WA2_VIDCMD_2X = 2,
+ WA2_VIDCMD_LIB = 3,
+ WA2_VIDPOPUP_MISC = 4,
+ WA2_VIDCMD_EXIT_FS = 5,
+ };
+
+ void sendVidCmd(int which, int x=0, int y=0, int menu_align_flag=0);
+ int hasVideoSupport();
+ int isPlayingVideo();
+ int isPlayingVideoFullscreen();
+ int isDoubleSize();
+ int getTimeDisplayMode();
+
+ void toggleVis();
+ int isVisRunning();
+ HWND getVisWnd();
+
+ IDropTarget *getDropTarget();
+
+ int getBitrate(); // in kbps
+ int getSamplerate(); // in khz
+ int getChannels(); // 1 mono, 2 stereo ...
+
+ int isValidEmbedWndState(embedWindowState *ws);
+
+ int PE_getNumItems();
+ fileinfo2 *PE_getFileTitle(int index);
+ fileinfo2W *PE_getFileTitleW(int index);
+ int PE_getCurrentIndex();
+ void PE_setCurrentIndex(int i);
+
+ void switchSkin(const wchar_t *skinname);
+ void visNext();
+ void visPrev();
+ void visRandom(int set);
+ void pollVisRandom();
+ void visFullscreen();
+ void visConfig();
+ void visMenu();
+
+ void setIdealVideoSize(int w, int h) { video_ideal_width = w; video_ideal_height = h; }
+ void getIdealVideoSize(int *w, int *h);
+
+ int getStopOnVideoClose();
+ void setStopOnVideoClose(int stop);
+
+ int GetVideoResize();
+ void SetVideoResize(int stop);
+
+ virtual int isVis(HWND hwnd); // checks children too
+
+ HWND getPreferencesWindow();
+ void setPlEditWidthHeight(int width, int height);
+
+ HINSTANCE getLanguagePackInstance();
+
+ void openTrackInfo();
+ const char *getOutputPlugin();
+
+ void setDrawBorders(int d);
+ void disableSkinnedCursors(int disable);
+
+ int getMetaData(const wchar_t *filename, const wchar_t *name, wchar_t *data, int data_len);
+ void GetFileInfo(const wchar_t *filename, wchar_t *title, int titleCch, int *length);
+
+ void invalidateCache();
+
+ const char *getVideoInfoString();
+
+ void playFile(const wchar_t *file);
+ void rewind5s();
+ void forward5s();
+ void endOfPlaylist();
+ void startOfPlaylist();
+ void stopWithFade();
+ void stopAfterCurrent();
+
+ void clearPlaylist();
+
+ int isWindowShade(int wnd);
+
+ int getCurTrackRating();
+ void setCurTrackRating(int rating);
+
+ int isExitEnabled();
+ int pushExitDisabled();
+ int popExitDisabled();
+
+
+ int DownloadFile(const char *url, const wchar_t *destfilepath = L"", bool addToMl = true, bool notifyDownloadsList = true);
+ void getDownloadPath(wchar_t path2store[MAX_PATH]);
+ void setDownloadPath(const wchar_t * path2store);
+
+ bool GetAlbumArt(const wchar_t *filename);
+ bool IsWinampPro();
+
+private:
+ void setFoundVis() { foundvis = 1; }
+ char *m_version;
+ HWND hwnd_winamp;
+ HWND hwnd_playlist;
+ int foundvis;
+ int enabled;
+ int visible;
+ int video_ideal_width;
+ int video_ideal_height;
+ DWORD cached_length_time;
+ int got_length_cache;
+ int cached_length;
+
+ DWORD cached_pos_time;
+ int got_pos_cache;
+ int cached_pos;
+
+ int saved_video,
+#ifdef MINIBROWSER_SUPPORT
+ saved_mb,
+#endif
+ saved_pe, saved_eq, saved_main;
+};
+
+//-----------------------------------------------------------------------------------------------
+
+extern Winamp2FrontEnd wa2;
+
+BOOL DoTrackPopup(HMENU hMenu, UINT fuFlags, int x, int y, HWND hwnd);
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/wa2groupdefs.cpp b/Src/Plugins/General/gen_ff/wa2groupdefs.cpp
new file mode 100644
index 00000000..4075aaa4
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2groupdefs.cpp
@@ -0,0 +1,36 @@
+#include <precomp.h>
+#include "wa2groupdefs.h"
+#include <bfc/string/StringW.h>
+
+//-----------------------------------------------------------------------------------------------
+Wa2Groupdefs::Wa2Groupdefs() {
+ WASABI_API_SYSCB->syscb_registerCallback(this);
+}
+
+//-----------------------------------------------------------------------------------------------
+Wa2Groupdefs::~Wa2Groupdefs() {
+ WASABI_API_SYSCB->syscb_deregisterCallback(this);
+}
+
+//-----------------------------------------------------------------------------------------------
+int Wa2Groupdefs::skincb_onBeforeLoadingElements() {
+ StringW s;
+
+ // header
+
+ s = L"buf:"
+ L"<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\"?>"
+ L"<WinampAbstractionLayer version=\"0.8\">"
+
+ L"<groupdef id=\"library.content.group\">"
+ L" <windowholder hold=\"{6B0EDF80-C9A5-11d3-9F26-00C04F39FFC6}\" fitparent=\"1\" />"
+ L"</groupdef>";
+
+ // footer
+
+ s += L"</WinampAbstractionLayer>";
+
+ WASABI_API_SKIN->loadSkinFile(s);
+ return 1;
+}
+
diff --git a/Src/Plugins/General/gen_ff/wa2groupdefs.h b/Src/Plugins/General/gen_ff/wa2groupdefs.h
new file mode 100644
index 00000000..bcc61741
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2groupdefs.h
@@ -0,0 +1,18 @@
+#ifndef __WA2GROUPDEFS_H
+#define __WA2GROUPDEFS_H
+
+#include <api/syscb/callbacks/skincb.h>
+
+//-----------------------------------------------------------------------------------------------
+
+class Wa2Groupdefs : public SkinCallbackI {
+ public:
+ Wa2Groupdefs();
+ virtual ~Wa2Groupdefs();
+
+ int skincb_onBeforeLoadingElements();
+
+ private:
+};
+
+#endif
diff --git a/Src/Plugins/General/gen_ff/wa2playlist.cpp b/Src/Plugins/General/gen_ff/wa2playlist.cpp
new file mode 100644
index 00000000..696590d7
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2playlist.cpp
@@ -0,0 +1,2 @@
+#include <precomp.h>
+#include "wa2playlist.h"
diff --git a/Src/Plugins/General/gen_ff/wa2playlist.h b/Src/Plugins/General/gen_ff/wa2playlist.h
new file mode 100644
index 00000000..d86f8167
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2playlist.h
@@ -0,0 +1,11 @@
+#ifndef _WA2PLAYLIST_H
+#define _WA2PLAYLIST_H
+
+class Wa2Playlist
+{
+public:
+ Wa2Playlist() {}
+ virtual ~Wa2Playlist() {}
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/wa2pldirobj.cpp b/Src/Plugins/General/gen_ff/wa2pldirobj.cpp
new file mode 100644
index 00000000..66389851
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2pldirobj.cpp
@@ -0,0 +1,366 @@
+#include <precomp.h>
+#include "main.h"
+#include "wa2pldirobj.h"
+#include "wa2frontend.h"
+
+#include <bfc/util/timefmt.h>
+#include "wa2pledit.h"
+
+/*
+TODO:
+register for playlists callbacks so we can keep up to date
+drag&drop re-ordering
+in-place renaming
+widget for editing playlists
+
+*/
+const wchar_t plDirXuiObjectStr[] = L"PlaylistDirectory"; // This is the xml tag
+char plDirXuiSvcName[] = "Playlist Directory XUI object"; // this is the name of the xuiservice
+
+static PlDirScriptObjectController _pldirController;
+ScriptObjectController *pldirController = &_pldirController;
+
+BEGIN_SERVICES(wa2PlDirObj_Svcs);
+DECLARE_SERVICETSINGLE(svc_scriptObject, PlDirScriptObjectSvc);
+DECLARE_SERVICE(XuiObjectCreator<PlDirXuiSvc>);
+END_SERVICES(wa2PlDirObj_Svcs, _wa2PlDirObj_Svcs);
+
+#define CB_POPULATE 0x6273
+#ifdef _X86_
+extern "C"
+{
+ int _link_wa2PlDirObj_Svcs;
+}
+#else
+extern "C"
+{
+ int __link_wa2PlDirObj_Svcs;
+}
+#endif
+
+// -----------------------------------------------------------------------------------------------------
+// Service
+ScriptObjectController *PlDirScriptObjectSvc::getController(int n)
+{
+ switch (n)
+ {
+ case 0:
+ return pldirController;
+ }
+ return NULL;
+}
+
+// -----------------------------------------------------------------------------------------------------
+// PlDirObject
+PlDirObject::PlDirObject()
+{
+ getScriptObject()->vcpu_setInterface(PLDIR_SCRIPTOBJECT_GUID, (void *)static_cast<PlDirObject *>(this));
+ getScriptObject()->vcpu_setClassName(L"PlDir");
+ getScriptObject()->vcpu_setController(pldirController);
+
+ _pldirController.mylist.addItem(this);
+}
+
+PlDirObject::~PlDirObject()
+{
+ int numItems = getItemCount();
+
+ for (int i=0;i<numItems;i++)
+ {
+ GUID *playlist_guid = (GUID *)getItemData(i);
+ if (playlist_guid)
+ delete playlist_guid;
+ }
+
+ if (WASABI_API_SYSCB) WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<PlaylistCallbackI *>(this));
+ _pldirController.mylist.removeItem(this);
+}
+
+int PlDirObject::playlistcb_added(size_t index)
+{
+ postDeferredCallback(CB_POPULATE);
+ return 1;
+}
+
+int PlDirObject::playlistcb_saved(size_t index)
+{
+ postDeferredCallback(CB_POPULATE);
+ return 1;
+}
+
+int PlDirObject::onDeferredCallback(intptr_t p1, intptr_t p2)
+{
+ if (p1 == CB_POPULATE)
+ {
+ Populate();
+ return 1;
+ }
+ return ListWnd::onDeferredCallback(p1, p2);
+}
+
+void PlDirObject::Populate()
+{
+ int numItems = getItemCount();
+
+ for (int i=0;i<numItems;i++)
+ {
+ GUID *playlist_guid = (GUID *)getItemData(i);
+ if (playlist_guid)
+ delete playlist_guid;
+ }
+
+ deleteAllItems();
+ if (AGAVE_API_PLAYLISTS)
+ {
+ AGAVE_API_PLAYLISTS->Lock();
+ size_t count = AGAVE_API_PLAYLISTS->GetCount();
+ for (size_t i=0;i!=count;i++)
+ {
+ const wchar_t *playlistName = AGAVE_API_PLAYLISTS->GetName(i);
+ GUID *playlist_guid = new GUID(AGAVE_API_PLAYLISTS->GetGUID(i));
+ addItem(playlistName, (LPARAM)playlist_guid); // TODO: malloc pointer to GUID and store
+ wchar_t temp[256] = {0};
+ size_t numItems=0;
+ AGAVE_API_PLAYLISTS->GetInfo(i, api_playlists_itemCount, &numItems, sizeof(numItems));
+ WCSNPRINTF(temp, 256, L"%u", numItems);
+ this->setSubItem(i, 1, temp);
+ AGAVE_API_PLAYLISTS->GetInfo(i, api_playlists_totalTime, &numItems, sizeof(numItems)); //numitems holds now time
+ wchar_t buf[1024] = {0};
+ TimeFmt::printHourMinSec(numItems, buf, 1024, 1);
+ this->setSubItem(i, 2, buf);
+ }
+ AGAVE_API_PLAYLISTS->Unlock();
+ }
+}
+
+int PlDirObject::onInit()
+{
+ /*colresize = 1;
+ resizing_col = true;
+ colresizeo = 1;*/
+
+ ListWnd::onInit();
+ setName(L"Playlists");
+ //setItemIcon(
+ //setShowColumnsHeaders(FALSE);
+ ListColumn *nameCol = new ListColumn(L"Playlist Title", 1);
+ //nameCol->setWidth(100);
+ insertColumn(nameCol);
+ /*ListColumn *countCol= new ListColumn(L"Items", 0);
+ countCol->setWidth(40);
+ countCol->setAlignment(COL_RIGHTALIGN);
+ insertColumn(countCol,1,COL_RIGHTALIGN);
+ ListColumn *lenCol= new ListColumn(L"Time", 0);
+ lenCol->setWidth(50);
+ lenCol->setAlignment(COL_CENTERALIGN);
+ insertColumn(lenCol, 1, COL_CENTERALIGN);
+ insertColumn(lenCol);*/
+ addColumn(L"Items", 40, 0, COL_RIGHTALIGN);
+ addColumn(L"Time", 55, 0, COL_RIGHTALIGN);
+
+ //addColumn(L"Time", 100);
+ Populate();
+
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<PlaylistCallbackI *>(this));
+
+ return 1;
+}
+/*
+int PlDirObject::onResize()
+{
+ ListWnd::onResize();
+ RECT r;
+ getClientRect(&r);
+ ListColumn *lc = getColumn(0);
+ lc->setWidth(r.right - r.left);
+ return 1;
+}*/
+
+void PlDirObject::onDoubleClick(int itemnum)
+{
+ ListWnd::onDoubleClick(itemnum);
+ // find a playlisteditor object near us
+ Wa2PlaylistEditor *editor = static_cast<Wa2PlaylistEditor *>(findWindowByInterface(Wa2PlaylistEditor::getInterfaceGuid()));
+ if (editor != NULL)
+ {
+ Wa2Playlist *playlist = getPlaylist(itemnum);
+ editor->setPlaylist(playlist);
+ }
+ GUID *playlist_guid = (GUID *)this->getItemData(itemnum);
+ if (playlist_guid)
+ {
+ size_t index;
+ AGAVE_API_PLAYLISTS->Lock();
+ if (AGAVE_API_PLAYLISTS->GetPosition(*playlist_guid, &index) == API_PLAYLISTS_SUCCESS)
+ {
+ // TODO: benski> try to retrieve setting from ml_playlists for play vs enqueue on double click
+ const wchar_t *playlist_filename = AGAVE_API_PLAYLISTS->GetFilename(index);
+ wa2.playFile(playlist_filename);
+ }
+ AGAVE_API_PLAYLISTS->Unlock();
+ }
+}
+
+Wa2Playlist *PlDirObject::getPlaylist(int itemnum)
+{
+ return (Wa2Playlist *) - 1;
+}
+
+// -----------------------------------------------------------------------------------------------------
+// PlDirScriptObjectController
+
+function_descriptor_struct PlDirScriptObjectController::exportedFunction[] = {
+ {L"showCurrentlyPlayingEntry", 0, (void*)PlDirScriptObjectController::pldir_showCurrentlyPlayingEntry},
+ {L"getNumItems", 0, (void*)PlDirScriptObjectController::pldir_getNumItems},
+ {L"renameItem", 2, (void*)PlDirScriptObjectController::pldir_renameItem},
+ {L"getItemName", 1, (void*)PlDirScriptObjectController::pldir_getItemName},
+ {L"playItem", 1, (void*)PlDirScriptObjectController::pldir_playItem},
+ {L"enqueueItem", 1, (void*)PlDirScriptObjectController::pldir_enqueueItem},
+ {L"refresh", 0, (void*)PlDirScriptObjectController::pldir_refresh},
+};
+
+int PlDirScriptObjectController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+ScriptObject *PlDirScriptObjectController::instantiate()
+{
+ PlDirObject *c = new PlDirObject;
+ if (!c) return NULL;
+ return c->getScriptObject();
+}
+
+void PlDirScriptObjectController::destroy(ScriptObject *o)
+{
+ PlDirObject *obj = static_cast<PlDirObject *>(o->vcpu_getInterface(PLDIR_SCRIPTOBJECT_GUID));
+ ASSERT(obj != NULL);
+ delete obj;
+}
+
+PlDirScriptObjectController::~PlDirScriptObjectController()
+{
+ // Destroy our list, otherwise we get a big bang on wasabi shutdown
+ if (_pldirController.mylist.getNumItems() > 0)
+ _pldirController.mylist.deleteAll();
+}
+
+void *PlDirScriptObjectController::encapsulate(ScriptObject *o)
+{
+ return NULL; // nobody can inherits from me yet (see rootobj or guiobj in studio if you want to allow that)
+}
+
+void PlDirScriptObjectController::deencapsulate(void *)
+{}
+
+// Script calls
+scriptVar PlDirScriptObjectController::pldir_showCurrentlyPlayingEntry(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+
+ HWND hPeWindow = wa2.getWnd(IPC_GETWND_PE);
+ SendMessageW(hPeWindow, WM_USER, 666, wa2.PE_getCurrentIndex());
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar PlDirScriptObjectController::pldir_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+
+ AGAVE_API_PLAYLISTS->Lock();
+ size_t n = AGAVE_API_PLAYLISTS->GetCount();
+ AGAVE_API_PLAYLISTS->Unlock();
+
+ return MAKE_SCRIPT_INT(n);
+}
+
+scriptVar PlDirScriptObjectController::pldir_refresh(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+
+ for (int i = 0; i < _pldirController.mylist.getNumItems(); i++)
+ {
+ PlDirObject *p = _pldirController.mylist.enumItem(i);
+ if (p) p->Populate();
+ }
+
+ // TODO: add refresh for ml pl view!
+ //HWND hMlWindow = wa2.getMediaLibrary();
+ //SendMessageW(hMlWindow, ???);
+
+ //AGAVE_API_PLAYLISTS->MoveBefore(2,1);
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar PlDirScriptObjectController::pldir_renameItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item, scriptVar name)
+{
+ SCRIPT_FUNCTION_INIT
+
+ AGAVE_API_PLAYLISTS->Lock();
+ AGAVE_API_PLAYLISTS->RenamePlaylist(GET_SCRIPT_INT(item), GET_SCRIPT_STRING(name));
+ AGAVE_API_PLAYLISTS->Unlock();
+
+ for (int i = 0; i < _pldirController.mylist.getNumItems(); i++)
+ {
+ PlDirObject* p = _pldirController.mylist.enumItem(i);
+ if (p) p->Populate();
+ }
+
+ //AGAVE_API_PLAYLISTS->MoveBefore(2,1);
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar PlDirScriptObjectController::pldir_getItemName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+
+ AGAVE_API_PLAYLISTS->Lock();
+ const wchar_t *k = AGAVE_API_PLAYLISTS->GetName(GET_SCRIPT_INT(item));
+ AGAVE_API_PLAYLISTS->Unlock();
+
+ return MAKE_SCRIPT_STRING(k);
+}
+
+scriptVar PlDirScriptObjectController::pldir_playItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _itemnum)
+{
+ SCRIPT_FUNCTION_INIT
+ int itemnum = GET_SCRIPT_INT(_itemnum);
+
+ GUID playlist_guid = AGAVE_API_PLAYLISTS->GetGUID(itemnum);
+
+ size_t index;
+ AGAVE_API_PLAYLISTS->Lock();
+ if (AGAVE_API_PLAYLISTS->GetPosition(playlist_guid, &index) == API_PLAYLISTS_SUCCESS)
+ {
+ // TODO: benski> try to retrieve setting from ml_playlists for play vs enqueue on double click
+ const wchar_t *playlist_filename = AGAVE_API_PLAYLISTS->GetFilename(index);
+ wa2.playFile(playlist_filename);
+ }
+ AGAVE_API_PLAYLISTS->Unlock();
+
+ RETURN_SCRIPT_VOID
+}
+
+scriptVar PlDirScriptObjectController::pldir_enqueueItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _itemnum)
+{
+ SCRIPT_FUNCTION_INIT
+
+ int itemnum = GET_SCRIPT_INT(_itemnum);
+
+ GUID playlist_guid = AGAVE_API_PLAYLISTS->GetGUID(itemnum);
+
+ size_t index;
+ AGAVE_API_PLAYLISTS->Lock();
+ if (AGAVE_API_PLAYLISTS->GetPosition(playlist_guid, &index) == API_PLAYLISTS_SUCCESS)
+ {
+ // TODO: benski> try to retrieve setting from ml_playlists for play vs enqueue on double click
+ const wchar_t *playlist_filename = AGAVE_API_PLAYLISTS->GetFilename(index);
+ wa2.enqueueFile(playlist_filename);
+ }
+ AGAVE_API_PLAYLISTS->Unlock();
+
+ RETURN_SCRIPT_VOID
+} \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/wa2pldirobj.h b/Src/Plugins/General/gen_ff/wa2pldirobj.h
new file mode 100644
index 00000000..59a1d9b1
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2pldirobj.h
@@ -0,0 +1,105 @@
+#pragma once
+#include <api/script/objects/rootobj.h>
+#include <api/script/objcontroller.h>
+#include <api/script/scriptobj.h>
+#include <bfc/depend.h>
+#include <api/service/svcs/svc_scriptobji.h>
+#include <api/wnd/wndclass/listwnd.h>
+#include "wa2playlist.h"
+#include <api/syscb/callbacks/playlistcb.h>
+#include <api/service/svcs/svc_scriptobji.h>
+
+class PlDirObject;
+
+extern ScriptObjectController *pldirController;
+
+// -----------------------------------------------------------------------------------------------------
+// ScriptObject Service
+class PlDirScriptObjectSvc : public svc_scriptObjectI {
+
+public:
+ PlDirScriptObjectSvc() {};
+ virtual ~PlDirScriptObjectSvc() {};
+
+ static const char *getServiceName() { return "PlDir script object"; }
+ virtual ScriptObjectController *getController(int n);
+};
+
+// -----------------------------------------------------------------------------------------------------
+// Script classe GUIDS
+
+// {61A7ABAD-7D79-41f6-B1D0-E1808603A4F4}
+static const GUID PLDIR_SCRIPTOBJECT_GUID =
+{ 0x61a7abad, 0x7d79, 0x41f6, { 0xb1, 0xd0, 0xe1, 0x80, 0x86, 0x3, 0xa4, 0xf4 } };
+
+// -----------------------------------------------------------------------------------------------------
+// ScriptObject Interface
+
+// PlDir
+class PlDirObject : public ListWnd, public PlaylistCallbackI
+{
+ public:
+
+ PlDirObject();
+ virtual ~PlDirObject();
+
+ virtual int onInit();
+ //virtual int onResize();
+ virtual int wantResizeCols() { return 0; }
+ virtual int wantHScroll() { return 0; }
+
+ virtual void onDoubleClick(int itemnum);
+ virtual Wa2Playlist *getPlaylist(int itemnum);
+
+ /* PlaylistCallbackI method overrides */
+ int playlistcb_added(size_t index);
+ int playlistcb_saved(size_t index);
+
+
+ int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+ void Populate();
+ private:
+ PtrList<Wa2Playlist> playlists;
+
+};
+
+// -----------------------------------------------------------------------------------------------------
+// ScriptObjectControllers for our script classes
+
+// PlDir
+class PlDirScriptObjectController : public ScriptObjectControllerI {
+ public:
+ virtual const wchar_t *getClassName() { return L"PlDir"; }
+ virtual const wchar_t *getAncestorClassName() { return L"Object"; }
+ virtual ScriptObjectController *getAncestorController() { return NULL; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions() { return exportedFunction; }
+ virtual GUID getClassGuid() { return PLDIR_SCRIPTOBJECT_GUID; }
+ virtual int getInstantiable() { return 0; }
+ virtual int getReferenceable() { return 0; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ virtual ~PlDirScriptObjectController();
+
+ // Maki functions table
+ static scriptVar pldir_showCurrentlyPlayingEntry(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar pldir_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar pldir_renameItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item, scriptVar name);
+ static scriptVar pldir_getItemName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item);
+ static scriptVar pldir_playItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item);
+ static scriptVar pldir_enqueueItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item);
+ static scriptVar pldir_refresh(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ PtrList<PlDirObject> mylist;
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+};
+
+extern const wchar_t plDirXuiObjectStr[];
+extern char plDirXuiSvcName[];
+class PlDirXuiSvc : public XuiObjectSvc<PlDirObject, plDirXuiObjectStr, plDirXuiSvcName> {};
+
diff --git a/Src/Plugins/General/gen_ff/wa2pledit.cpp b/Src/Plugins/General/gen_ff/wa2pledit.cpp
new file mode 100644
index 00000000..99b021fb
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2pledit.cpp
@@ -0,0 +1,241 @@
+#include <precomp.h>
+#include "wa2pledit.h"
+#include <api/script/objects/PlaylistScriptObject.h>
+#include <tataki/color/skinclr.h>
+#include "wa2frontend.h"
+#include <tataki/canvas/bltcanvas.h>
+#include "../nu/AutoWide.h"
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(Wa2Pledit_Svc);
+DECLARE_SERVICE(XuiObjectCreator<Wa2PleditXuiSvc>);
+END_SERVICES(Wa2Pledit_Svc, _Wa2Pledit_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_Wa2PleditXuiSvc; }
+#else
+extern "C" { int __link_Wa2PleditXuiSvc; }
+#endif
+
+#endif
+
+// -----------------------------------------------------------------------
+const wchar_t Wa2PleditXuiObjectStr[] = L"PlaylistEditor"; // This is the xml tag
+char Wa2PleditXuiSvcName[] = "Playlist Editor xui object";
+
+// -----------------------------------------------------------------------
+
+#define TRACKLENGTH_WIDTH 40
+#define DC_CURRENTIDX 10
+#define DC_PLAY 11
+#define TIMER_REFRESHLIST 12
+
+static SkinColor text(L"pledit.text"), rotext(L"pledit.text.readonly");
+static SkinColor text_disabled(L"pledit.text.disabled");
+static SkinColor bgcolor(L"pledit.bgcolor");
+static SkinColor currenttext(L"wasabi.itemlist.outline.focus");
+static SkinColor currentoutline(L"wasabi.itemlist.outline.current");
+
+PtrList<Wa2PlaylistEditor> Wa2PlaylistEditor::editors;
+
+COLORREF Wa2PlaylistEditor::getTextColor(LPARAM lParam) {
+// if (playlist == NULL) return text;
+// PlaylistEntry *entry = playlist->enumEntry(lParam);
+// if (entry && entry->getCurrent())
+// return currenttext;
+// else
+ if (lParam == cur_index)
+ return currenttext;
+ return text;
+}
+
+COLORREF Wa2PlaylistEditor::getBgColor(LPARAM lParam) {
+ return bgcolor;
+}
+
+COLORREF Wa2PlaylistEditor::getFocusRectColor(LPARAM lParam) {
+ return currentoutline;
+}
+
+int Wa2PlaylistEditor::needFocusRect(LPARAM lParam)
+{
+ return lParam == cur_index;
+}
+
+Wa2PlaylistEditor::Wa2PlaylistEditor()
+: curplaylist(0)
+{
+ curplaylist = NULL;
+ cur_index = wa2.PE_getCurrentIndex()+1;
+}
+
+Wa2PlaylistEditor::~Wa2PlaylistEditor() {
+ killTimer(TIMER_REFRESHLIST);
+ editors.removeItem(this);
+}
+
+int Wa2PlaylistEditor::onInit()
+{
+ WA2PLAYLISTEDITOR_PARENT::onInit();
+ setShowColumnsHeaders(FALSE);
+ addColumn(L"Track #", calcTrackNumWidth());
+ addColumn(L"Track Name", 200);
+ addColumn(L"Length", TRACKLENGTH_WIDTH, 1, COL_RIGHTALIGN);
+ editors.addItem(this);
+ return 1;
+}
+
+void Wa2PlaylistEditor::onVScrollToggle(int set) {
+ resizeCols();
+}
+
+int Wa2PlaylistEditor::onResize() {
+ WA2PLAYLISTEDITOR_PARENT::onResize();
+ resizeCols();
+ return 1;
+}
+
+void Wa2PlaylistEditor::resizeCols() {
+ RECT r;
+ getClientRect(&r);
+ ListColumn *c0 = getColumn(0);
+ int tw = calcTrackNumWidth();
+ c0->setWidth(tw);
+ ListColumn *c1 = getColumn(1);
+ c1->setWidth(r.right-r.left - tw - TRACKLENGTH_WIDTH);
+}
+
+int Wa2PlaylistEditor::calcTrackNumWidth()
+{
+ WndCanvas bc(this);
+ Wasabi::FontInfo fontInfo;
+ fontInfo.pointSize = getFontSize();
+ int cw = getFontSize();
+ int dw = 8;
+ bc.getTextExtent(L"W", &cw, NULL, &fontInfo);
+ bc.getTextExtent(L".", &dw, NULL, &fontInfo);
+ int n = getNumItems();
+ if (n < 0) return dw+cw;
+ float f = log10((float)n);
+ int l = (int)ceil(f);
+ return (l * cw) + dw + 5;
+}
+
+void *Wa2PlaylistEditor::getInterface(GUID interface_guid) {
+ if (interface_guid == Wa2PlaylistEditor::getInterfaceGuid()) {
+ return this;
+ }
+ return WA2PLAYLISTEDITOR_PARENT::getInterface(interface_guid);
+}
+
+void Wa2PlaylistEditor::setPlaylist(Wa2Playlist *playlist) {
+ if (curplaylist == playlist)
+ return;
+ curplaylist = playlist;
+ loadList();
+}
+
+void Wa2PlaylistEditor::_loadList() {
+ int y = getScrollY();
+
+ setRedraw(FALSE);
+
+ deleteAllItems();
+
+ if (curplaylist == (Wa2Playlist *)-1) {
+
+ // load the current playlist (the one in the real playlist editor)
+ int n = wa2.PE_getNumItems();
+
+ for (int i=0;i<n;i++)
+ {
+ fileinfo2 *fi = wa2.PE_getFileTitle(i);
+ addItem(StringPrintfW(L"%d.", i+1), i+1);
+ setSubItem(i, 1, AutoWide(fi->filetitle));
+ setSubItem(i, 2, AutoWide(fi->filelength));
+ }
+ } else {
+ // load an available playlist
+ }
+
+ RECT r;
+ getClientRect(&r);
+ int ch = getContentsHeight();
+ if (ch - y >= r.bottom-r.top) scrollToY(y);
+ else if (ch - r.bottom-r.top >= 0) scrollToY(ch - r.bottom-r.top);
+ else scrollToY(0);
+
+ resizeCols();
+
+ postDeferredCallback(DC_CURRENTIDX);
+ setRedraw(TRUE);
+}
+
+void Wa2PlaylistEditor::_onNewCurrentIndex(int idx)
+{
+ foreach(editors)
+ editors.getfor()->onNewCurrentIndex(idx);
+ endfor
+}
+
+void Wa2PlaylistEditor::onNewCurrentIndex(int idx)
+{
+ if (idx!=cur_index)
+ {
+ int oldIdx = cur_index;
+ cur_index = idx;
+ invalidateItem(oldIdx);
+ invalidateItem(idx);
+ }
+}
+
+void Wa2PlaylistEditor::onSetVisible(int show) {
+ WA2PLAYLISTEDITOR_PARENT::onSetVisible(show);
+ if (!show) getParent()->setFocus();
+}
+
+void Wa2PlaylistEditor::onPlaylistModified() {
+ if (curplaylist == (Wa2Playlist *)-1)
+ loadList();
+}
+
+void Wa2PlaylistEditor::_onPlaylistModified() {
+ // fist call the Pledit script object
+ SPlaylist::onPleditModified();
+ // than all our old pledit xml objects
+ foreach(editors)
+ editors.getfor()->onPlaylistModified();
+ endfor
+}
+
+int Wa2PlaylistEditor::onDeferredCallback(intptr_t p1, intptr_t p2)
+{
+ if (p1 == DC_CURRENTIDX)
+ {
+ onNewCurrentIndex(wa2.PE_getCurrentIndex()+1);
+ return 1;
+ }
+ return WA2PLAYLISTEDITOR_PARENT::onDeferredCallback(p1, p2);
+}
+
+void Wa2PlaylistEditor::onDoubleClick(int itemnum)
+{
+ WA2PLAYLISTEDITOR_PARENT::onDoubleClick(itemnum);
+ wa2.PE_setCurrentIndex(itemnum);
+ wa2.userButton(WA2_USERBUTTON_PLAY, 0);
+ _onNewCurrentIndex(itemnum+1);
+}
+
+void Wa2PlaylistEditor::timerCallback(int id)
+{
+ if (id == TIMER_REFRESHLIST) {
+ killTimer(TIMER_REFRESHLIST);
+ _loadList();
+ }
+}
+
+void Wa2PlaylistEditor::loadList()
+{
+ killTimer(TIMER_REFRESHLIST);
+ setTimer(TIMER_REFRESHLIST, 500);
+}
diff --git a/Src/Plugins/General/gen_ff/wa2pledit.h b/Src/Plugins/General/gen_ff/wa2pledit.h
new file mode 100644
index 00000000..9c08f1d8
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2pledit.h
@@ -0,0 +1,68 @@
+#ifndef _WA2PLEDIT_H
+#define _WA2PLEDIT_H
+
+#include <api/wnd/wndclass/listwnd.h>
+#include "wa2playlist.h"
+
+#define WA2PLAYLISTEDITOR_PARENT ListWnd
+
+class Wa2PlaylistEditor;
+
+class Wa2PlaylistEditor : public WA2PLAYLISTEDITOR_PARENT
+{
+public:
+ static GUID getInterfaceGuid()
+ {
+ // {265947B2-3EDB-453e-B748-EC17890F4FE4}
+ const GUID guid =
+ { 0x265947b2, 0x3edb, 0x453e, { 0xb7, 0x48, 0xec, 0x17, 0x89, 0xf, 0x4f, 0xe4 } };
+ return guid;
+ }
+
+ Wa2PlaylistEditor();
+ virtual ~Wa2PlaylistEditor();
+
+ virtual int onInit();
+ virtual int onResize();
+ virtual int wantHScroll() { return 0; }
+ virtual void onVScrollToggle( int set );
+ virtual COLORREF getTextColor( LPARAM lParam );
+ virtual COLORREF getBgColor( LPARAM lParam );
+ virtual void *getInterface( GUID interface_guid );
+ virtual void setPlaylist( Wa2Playlist *playlist ); // -1 for working playlist
+ virtual int needFocusRect( LPARAM lParam );
+ virtual COLORREF getFocusRectColor( LPARAM lParam );
+ virtual void onSetVisible( int show );
+ virtual int onDeferredCallback( intptr_t p1, intptr_t p2 );
+ virtual void timerCallback( int id );
+ virtual void onDoubleClick( int itemnum );
+
+ // object
+ virtual void onNewCurrentIndex( int idx );
+ virtual void onPlaylistModified();
+
+ // class
+ static void _onNewCurrentIndex( int idx );
+ static void _onPlaylistModified();
+ virtual void loadList();
+
+private:
+ void _loadList();
+ void resizeCols();
+ int calcTrackNumWidth();
+
+ Wa2Playlist *curplaylist;
+ static PtrList<Wa2PlaylistEditor> editors;
+ int cur_index;
+};
+
+// -----------------------------------------------------------------------
+extern const wchar_t Wa2PleditXuiObjectStr[];
+extern char Wa2PleditXuiSvcName[];
+
+class Wa2PleditXuiSvc : public XuiObjectSvc<Wa2PlaylistEditor, Wa2PleditXuiObjectStr, Wa2PleditXuiSvcName> {};
+
+
+#endif
+
+
diff --git a/Src/Plugins/General/gen_ff/wa2songticker.cpp b/Src/Plugins/General/gen_ff/wa2songticker.cpp
new file mode 100644
index 00000000..8067b056
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2songticker.cpp
@@ -0,0 +1,483 @@
+#include <precomp.h>
+#include "wa2songticker.h"
+#include <api.h>
+#include <tataki/color/skinclr.h>
+#include <api/core/api_core.h>
+#include <api/application/api_application.h>
+#include <wasabicfg.h>
+#include "wa2frontend.h"
+#include <api/skin/skinelem.h>
+#include <api/skin/skinparse.h>
+#include <api/config/items/attribs.h>
+#include <api/config/api_config.h>
+
+// {9149C445-3C30-4e04-8433-5A518ED0FDDE}
+static const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+
+// {280876CF-48C0-40bc-8E86-73CE6BB462E5}
+static const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+
+const wchar_t songtickerXuiObjectStr[] = L"SongTicker"; // This is the xml tag
+char songtickerXuiSvcName[] = "Song Ticker XUI object"; // this is the name of the xuiservice
+
+BEGIN_SERVICES(wa2SongTicker_Svcs);
+DECLARE_SERVICE(XuiObjectCreator<SongTickerXuiSvc>);
+END_SERVICES(wa2SongTicker_Svcs, _wa2SongTicker_Svcs);
+
+#ifdef _X86_
+extern "C"
+{
+ int _link_wa2SongTicker_Svcs;
+}
+#else
+extern "C"
+{
+ int __link_wa2SongTicker_Svcs;
+}
+#endif
+
+extern _float cfg_uioptions_textspeed;
+extern _int cfg_uioptions_textincrement;
+
+#define TIMER_SONGTICKER_SCROLL 0x777
+//#define SONGTICKER_SCROLL_MS 200 // TODO: make adjustable (api_config, xml param, maki script object)
+#define SONGTICKER_INCREMENT_PIXELS (cfg_uioptions_textincrement) // TODO: make adjustable?
+#define SONGTICKER_SCROLL_MS ((13.0f*(float)cfg_uioptions_textincrement)/cfg_uioptions_textspeed)
+#define SONGTICKER_SCROLL_ONE_PIXEL_MS (13.0f/cfg_uioptions_textspeed)
+#define SONGTICKER_SKIP_MS 2000 // TODO: make adjustable
+
+XMLParamPair SongTicker::params[] =
+{
+ {SONGTICKER_TICKER, L"TICKER"},
+};
+
+SongTicker::SongTicker()
+{
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+ song_title[0]=0;
+ song_length=-1;
+ position=0;
+ tickerMode=TICKER_SCROLL;
+ ticker_direction=1;
+ skipTimers=0;
+ grab_x = 0;
+ last_tick = Wasabi::Std::getTickCount();
+ buffer_hw_valid=false;
+ textW=0;
+
+ /* register XML parameters */
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+
+ CfgItem *ci=WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid);
+ if (ci)
+ {
+ viewer_addViewItem(ci->getDependencyPtr());
+ }
+
+ ci=WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid);
+ if (ci)
+ {
+ viewer_addViewItem(ci->getDependencyPtr());
+ }
+}
+
+void SongTicker::CreateXMLParameters(int master_handle)
+{
+ //SONGTICKER_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+SongTicker::~SongTicker()
+{
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+// TODO: benski> is this the right place for this?
+ killTimer(TIMER_SONGTICKER_SCROLL);
+}
+
+int SongTicker::onResize()
+{
+ killTimer(TIMER_SONGTICKER_SCROLL);
+ buffer_hw_valid=false;
+ invalidateBuffer();
+ return SONGTICKER_PARENT::onResize();
+}
+
+int SongTicker::onInit()
+{
+ int r = SONGTICKER_PARENT::onInit();
+ BuildTitle();
+ return r;
+}
+
+int SongTicker::corecb_onTitleChange(const wchar_t *title)
+{
+ BuildTitle();
+ return 1;
+}
+
+int SongTicker::corecb_onLengthChange(int newlength)
+{
+ song_length = newlength;
+ return 1;
+}
+
+void SongTicker::BuildTitle()
+{
+ killTimer(TIMER_SONGTICKER_SCROLL);
+ const wchar_t *curFilename = wa2.GetCurrentFile();
+ if (curFilename && *curFilename)
+ {
+ wa2.GetFileInfo(curFilename, song_title, 1024, &song_length);
+ WASABI_API_MEDIACORE->core_setTitle(song_title);
+ }
+ else
+ {
+ song_title[0]=0;
+ song_length=-1;
+ }
+
+ if (!song_title[0] || ((unsigned long)song_title < 65536))
+ {
+ display = WASABI_API_APP->main_getVersionString();
+ }
+ else
+ {
+ // TODO: use TimeFmt:: to format the time
+ if (song_length >= 0)
+ display.printf(L"%s (%d:%02d)",song_title,song_length/60,song_length%60);
+ else
+ display.printf(L"%s",song_title);
+ }
+
+ rotatingDisplay.printf(L"%s *** %s", display, display);
+ TextInfoCanvas c(this);
+ Wasabi::FontInfo fontInfo;
+ GetFontInfo(&fontInfo);
+ width_of_str_padded = c.getTextWidth(display, &fontInfo) + lpadding - rpadding;
+ width_of_str = c.getTextWidth(rotatingDisplay, &fontInfo) - c.getTextWidth(display, &fontInfo);
+ buffer_hw_valid=false;
+ invalidateBuffer();
+}
+
+int SongTicker::onBufferPaint(BltCanvas *canvas, int w, int h)
+{
+ SONGTICKER_PARENT::onBufferPaint(canvas, w, h);
+
+ // TODO: benski> need to optimize this :)
+ RECT r = {0,0,w,h};
+ canvas->fillRect(&r, RGB(0, 0, 0));
+
+ getClientRect(&r);
+
+ Wasabi::FontInfo fontInfo;
+ GetFontInfo(&fontInfo);
+ /*
+ if (tickerMode == TICKER_OFF)
+ {
+ lpadding=min(lpadding, w);
+ w=max(w-lpadding+rpadding, 0);
+ canvas->textOut(lpadding, 0, w, h, display, &fontInfo);
+ return 1;
+ }
+ */
+ const int textAreaWidth = r.right - r.left;
+ StringW *whichString = &display;
+ if (width_of_str_padded > textAreaWidth) // too big to fit?
+ {
+ switch (tickerMode)
+ {
+ case TICKER_OFF:
+ {
+ int extra = width_of_str_padded - textAreaWidth;
+ if (position>extra)
+ position=extra;
+ if (position<0)
+ position=0;
+ }
+ break;
+
+ case TICKER_SCROLL:
+ {
+ // make sure our position isn't out of bounds
+ while (position < 0)
+ position += width_of_str;
+
+ position %= (width_of_str);
+
+ whichString = &rotatingDisplay;
+ skipTimers=0;
+ setTimer(TIMER_SONGTICKER_SCROLL, (int)SONGTICKER_SCROLL_MS);
+ }
+ break;
+
+ case TICKER_BOUNCE:
+ {
+ int extra = width_of_str_padded- textAreaWidth;
+ if (position < 0)
+ {
+ position=0;
+ ticker_direction=1;
+ skipTimers=(int)(SONGTICKER_SKIP_MS/SONGTICKER_SCROLL_MS);
+ }
+
+ if (position>=extra)
+ {
+ position=extra-1;
+ ticker_direction=-1;
+ skipTimers=(int)(SONGTICKER_SKIP_MS/SONGTICKER_SCROLL_MS);
+ }
+ if (position < 0)
+ position=0;
+ setTimer(TIMER_SONGTICKER_SCROLL, (int)SONGTICKER_SCROLL_MS);
+ }
+ break;
+ }
+ }
+ else // if there's enough room, just draw the string as-is
+ {
+ position=0;
+ }
+ int x =min(lpadding, w);
+ w=max(w-x+rpadding, 0);
+ canvas->textOut(lpadding, 0, w, h, whichString->getValueSafe(), &fontInfo);
+
+ return 1;
+}
+
+void SongTicker::timerCallback(int id)
+{
+ if (id == TIMER_SONGTICKER_SCROLL && !grab)
+ {
+ uint32_t this_tick = Wasabi::Std::getTickCount();
+ if (TICKER_OFF == tickerMode)
+ {
+ killTimer(TIMER_SONGTICKER_SCROLL);
+ return;
+ }
+ if (skipTimers)
+ {
+ last_tick=this_tick;
+ skipTimers--;
+ return;
+ }
+ int numTicks=SONGTICKER_INCREMENT_PIXELS;
+ if (this_tick > last_tick) // make sure we havn't wrapped around
+ {
+ numTicks = (int)((this_tick - last_tick) / SONGTICKER_SCROLL_ONE_PIXEL_MS);
+ last_tick += (uint32_t)(numTicks * SONGTICKER_SCROLL_ONE_PIXEL_MS); // we do this instead of last_tick = this_tick, so we get some error shaping
+ }
+ else
+ last_tick=this_tick;
+
+ // move the ticker
+ position+=(ticker_direction*numTicks);
+ // ask to be redrawn
+ if (numTicks)
+ invalidate();
+ }
+ else
+ SONGTICKER_PARENT::timerCallback(id);
+}
+
+void SongTicker::getBufferPaintSource(RECT *r)
+{
+ if (r)
+ {
+ RECT cr;
+ getClientRect(&cr);
+ const int textAreaWidth = cr.right - cr.left;
+ if (width_of_str_padded > textAreaWidth) // too big to fit?
+ {
+ switch (tickerMode)
+ {
+ case TICKER_OFF:
+ {
+ int extra = width_of_str_padded- textAreaWidth;
+ if (position>extra)
+ position=extra;
+ if (position<0)
+ position=0;
+ }
+ break;
+
+ case TICKER_SCROLL:
+ {
+ // make sure our position isn't out of bounds
+ while (position < 0)
+ position += width_of_str;
+
+ position %= (width_of_str);
+ }
+ break;
+
+ case TICKER_BOUNCE:
+ {
+ int extra = width_of_str_padded - textAreaWidth;
+
+ if (position>=extra)
+ {
+ position=extra-1;
+ ticker_direction=-1;
+ skipTimers=(int)(SONGTICKER_SKIP_MS/SONGTICKER_SCROLL_MS);
+ }
+
+ if (position < 0)
+ {
+ position=0;
+ ticker_direction=1;
+ skipTimers=(int)(SONGTICKER_SKIP_MS/SONGTICKER_SCROLL_MS);
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ position=0;
+ }
+ r->left = position;
+ r->right = cr.right - cr.left + position;
+ r->top = 0;
+ r->bottom = cr.bottom - cr.top;
+ }
+}
+
+void SongTicker::getBufferPaintSize(int *w, int *h)
+{
+ RECT r;
+ getClientRect(&r);
+ int _w = r.right - r.left;
+ int _h = r.bottom - r.top;
+
+ if (!buffer_hw_valid)
+ {
+ const int textAreaWidth = r.right - r.left;
+ StringW *whichString = &display;
+ if (width_of_str_padded > textAreaWidth && tickerMode == TICKER_SCROLL) // too big to fit?
+ {
+ whichString = &rotatingDisplay;
+ buffer_hw_valid=false;
+ }
+
+ TextInfoCanvas canvas(this);
+ Wasabi::FontInfo fontInfo;
+ GetFontInfo(&fontInfo);
+ textW = canvas.getTextWidth(whichString->getValueSafe(), &fontInfo);
+ //int textH = canvas.getTextHeight(whichString->getValueSafe(), &fontInfo);
+ textW = textW + lpadding - rpadding;
+ buffer_hw_valid=true;
+ }
+
+ *w = max(_w, textW);
+ *h = _h;//max(_h, textH);
+}
+
+int SongTicker::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval)
+{
+ if (xuihandle != _xuihandle) return SONGTICKER_PARENT::setXuiParam(_xuihandle, attrid, name, strval);
+ switch (attrid)
+ {
+ case SONGTICKER_TICKER:
+ if (!WCSICMP(strval, L"bounce"))
+ tickerMode=TICKER_BOUNCE;
+ else if (!WCSICMP(strval, L"scroll"))
+ {
+ tickerMode=TICKER_SCROLL;
+ ticker_direction=1;
+ }
+ else if (!WCSICMP(strval, L"off"))
+ {
+ tickerMode=TICKER_OFF;
+ position=0;
+ killTimer(TIMER_SONGTICKER_SCROLL);
+ }
+ buffer_hw_valid=false;
+ invalidateBuffer();
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int SongTicker::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source)
+{
+ int r = SONGTICKER_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+ if(!WCSICMP(action, L"rebuildtitle"))
+ BuildTitle();
+
+ return r;
+}
+
+int SongTicker::viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen)
+{
+ if (*classguid == *CfgItem::depend_getClassGuid())
+ {
+ if (event==CfgItem::Event_ATTRIBUTE_CHANGED)
+ {
+ CfgItem *ci = (CfgItem *)item->dependent_getInterface(CfgItem::depend_getClassGuid());
+ if (ci->getGuid() == uioptions_guid
+ && ptr && (WCSCASEEQLSAFE((const wchar_t *)ptr, L"Text Ticker Speed") || WCSCASEEQLSAFE((const wchar_t *)ptr, L"Text Ticker Increment")))
+ {
+ BuildTitle();
+ }
+ }
+ }
+
+ return 1;
+}
+
+int SongTicker::onLeftButtonDown(int x, int y)
+{
+ if (!SONGTICKER_PARENT::onLeftButtonDown(x, y))
+ {
+ grab = 0;
+ return 0;
+ }
+
+ grab = 1;
+ grab_x = x + position;
+ // onMouseMove(x,y);
+ return 1;
+}
+
+int SongTicker::onMouseMove(int x, int y)
+{
+
+ if (!SONGTICKER_PARENT::onMouseMove(x, y))
+ {
+ grab = 0;
+ }
+
+ //POINT pos = {x, y};
+ //clientToScreen(&pos);
+
+ if (!grab) return 1;
+
+ position = grab_x - x;
+
+ // this forces us to calculate wraparound for position
+ RECT dummy;
+ getBufferPaintSource(&dummy);
+
+ invalidate();
+ return 1;
+}
+
+int SongTicker::onLeftButtonUp(int x, int y)
+{
+ if (!SONGTICKER_PARENT::onLeftButtonUp(x, y))
+ {
+ grab = 0;
+ return 0;
+ }
+
+ grab = 0;
+ return 1;
+}
diff --git a/Src/Plugins/General/gen_ff/wa2songticker.h b/Src/Plugins/General/gen_ff/wa2songticker.h
new file mode 100644
index 00000000..2d5f53be
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2songticker.h
@@ -0,0 +1,108 @@
+#ifndef NULLSOFT_GEN_FF_WA2SONGTICKER_H
+#define NULLSOFT_GEN_FF_WA2SONGTICKER_H
+
+//#include <api/wnd/wndclass/bufferpaintwnd.h>
+#include <api/skin/widgets/textbase.h>
+#include <api/syscb/callbacks/corecbi.h>
+#include <tataki/color/skinclr.h>
+#include <bfc/depend.h>
+
+#define SONGTICKER_PARENT TextBase
+
+class SongTicker
+ : public SONGTICKER_PARENT, /* provides basic wasabi windowing functinoality */
+ public CoreCallbackI, /* to get title change updates */
+ public DependentViewerI /* for config callbacks*/
+{
+
+public:
+ SongTicker();
+ ~SongTicker();
+
+ enum TickerMode
+ {
+ TICKER_OFF,
+ TICKER_SCROLL,
+ TICKER_BOUNCE,
+ };
+
+ int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
+
+protected:
+/* BaseWnd */
+ virtual int onInit();
+ virtual int onBufferPaint(BltCanvas *canvas, int w, int h); // draw the song ticker here
+
+ /* TimerClient */
+ virtual void timerCallback(int id); // scroll the song ticker every # seconds
+
+ /* media core callbacks */
+ /* TODO: benski> some thoughts... this differs from current behaviour but might be an interesting idea
+ virtual int corecb_onStarted(); // start the ticker
+ virtual int corecb_onStopped(); // go back to showing Winamp version string
+ virtual int corecb_onPaused(); // pause the ticker
+ virtual int corecb_onUnpaused(); // unpause the ticker
+
+ // benski> currently unused in Winamp 5... might be worth implementing so we can draw text here
+ virtual int corecb_onStatusMsg(const wchar_t *text);
+ virtual int corecb_onWarningMsg(const wchar_t *text);
+ virtual int corecb_onErrorMsg(const wchar_t *text);
+ */
+
+ virtual int corecb_onTitleChange(const wchar_t *title);
+ // benski> not sure what the difference here is - virtual int corecb_onTitle2Change(const wchar_t *title2);
+ virtual int corecb_onLengthChange(int newlength);
+ void getBufferPaintSource(RECT *r);
+ virtual void getBufferPaintSize(int *w, int *h);
+
+ /* TextBase */
+ void invalidateTextBuffer()
+ {
+ invalidateBuffer();
+ }
+
+ int viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen);
+ int onLeftButtonDown(int x, int y);
+ int onMouseMove(int x, int y);
+ int onLeftButtonUp(int x, int y);
+
+ /*static */void CreateXMLParameters(int master_handle);
+ virtual int onResize();
+private:
+ int grab_x;
+
+ /* Title */
+ void BuildTitle();
+ wchar_t song_title[1024];
+ int song_length;
+ int position;
+ StringW display, rotatingDisplay;
+ int width_of_str, width_of_str_padded;
+
+ /* */
+ int textW;
+ bool buffer_hw_valid;
+
+ /* scroll timer */
+ TimerToken scroll_timer_id;
+ int ticker_direction;
+ TickerMode tickerMode;
+ int skipTimers;
+ uint32_t last_tick;
+
+ /* XML Parameters */
+ enum
+ {
+ SONGTICKER_TICKER,
+ };
+ static XMLParamPair params[];
+ int xuihandle;
+ int setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval);
+
+};
+
+extern const wchar_t songtickerXuiObjectStr[];
+extern char songtickerXuiSvcName[];
+class SongTickerXuiSvc : public XuiObjectSvc<SongTicker, songtickerXuiObjectStr, songtickerXuiSvcName> {};
+
+#endif
diff --git a/Src/Plugins/General/gen_ff/wa2wndembed.cpp b/Src/Plugins/General/gen_ff/wa2wndembed.cpp
new file mode 100644
index 00000000..bcd2aaac
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2wndembed.cpp
@@ -0,0 +1,946 @@
+#include <precomp.h>
+#include "wa2wndembed.h"
+#include "wa2frontend.h"
+#include "wa2buckitems.h"
+#include "embedwndguid.h"
+#include "main.h"
+#include <api/wnd/bucketitem.h>
+#include "resource.h"
+#include <api/wnd/wndclass/wndholder.h>
+#include <api/wndmgr/layout.h>
+#include "wa2cfgitems.h"
+#include "gen.h"
+#include "../Agave/Language/api_language.h"
+
+extern TList<HWND> forcedoffwnds;
+
+#define BUCKETITEM_WNDTYPE L"buck"
+#define WINAMP_OPTIONS_WINDOWSHADE_PL 40266
+ReentryFilterObject wndMsgFilter;
+
+int embedTable[] = {
+ IPC_GETWND_PE,
+#ifdef MINIBROWSER_SUPPORT
+ IPC_GETWND_MB,
+#endif
+
+ IPC_GETWND_VIDEO};
+
+extern int switching_skin;
+extern int going_fixedform;
+extern int going_freeform;
+extern HINSTANCE hInstance;
+//-----------------------------------------------------------------------------------------------
+void WaOsWndHost::onBeforeReparent(int host)
+{
+#if defined(_WIN64)
+ embedWindowState *ws = (embedWindowState *)GetWindowLong(getHWND(), GWLP_USERDATA);
+#else
+ embedWindowState* ws = (embedWindowState*)GetWindowLong(getHWND(), GWL_USERDATA);
+#endif
+ // 0x49474541 is related to keeping windows shown on litestep desktops
+ if (ws == NULL || (int)ws == 0x49474541)
+ {
+ HWND w = getHWND();
+ if (w == wa2.getWnd(IPC_GETWND_VIDEO))
+ {
+ // this tells the video to not trigger its callback on windowposchanged, otherwise it will generate a new IPC_ONSHOW
+ SendMessageW(w, WM_USER + 0x2, 0, 1);
+ }
+ return ;
+ }
+ ws->extra_data[EMBED_STATE_EXTRA_REPARENTING] = 1; // tell winamp to ignore show/hide events
+ if (!host)
+ {
+ ShowWindow(getHWND(), SW_HIDE);
+ if (!transfer && ((switching_skin && !Wa2WndEmbed::hadRememberedWndVisible(getHWND())) || !switching_skin))
+ {
+ PostMessage(getHWND(), WM_USER + 101, 0, 0);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+void WaOsWndHost::onAfterReparent(int host)
+{
+#if defined(_WIN64)
+ embedWindowState *ws = (embedWindowState *)GetWindowLong(getHWND(), GWLP_USERDATA);
+#else
+ embedWindowState* ws = (embedWindowState*)GetWindowLong(getHWND(), GWL_USERDATA);
+#endif
+ // 0x49474541 is related to keeping windows shown on litestep desktops
+ if (ws == NULL || (int)ws == 0x49474541)
+ {
+ HWND w = getHWND();
+ if (w == wa2.getWnd(IPC_GETWND_VIDEO))
+ {
+ // stop preventing handling of video windowposchanged
+ SendMessageW(w, WM_USER + 0x2, 0, 0);
+ }
+ return ;
+ }
+ ws->extra_data[EMBED_STATE_EXTRA_REPARENTING] = 0; // tell winamp NOT to ignore show/hide events anymore
+}
+
+//-----------------------------------------------------------------------------------------------
+int WaOsWndHost::onGetFocus()
+{
+ XuiOSWndHost::onGetFocus();
+ ifc_window *z = findWindowByInterface(windowHolderGuid);
+ if (z)
+ {
+ WindowHolder *wh = static_cast<WindowHolder*>(z->getInterface(windowHolderGuid));
+ if (wh && wh->wndholder_wantAutoFocus())
+ {
+ HWND w = getHWND();
+ if (IsWindow(w)) SetFocus(w);
+ }
+ }
+ return 1;
+}
+
+//-----------------------------------------------------------------------------------------------
+int WaOsWndHost::wantFocus()
+{
+ ifc_window *w = findWindowByInterface(windowHolderGuid);
+ if (w)
+ {
+ WindowHolder *wh = static_cast<WindowHolder*>(w->getInterface(windowHolderGuid));
+ if (wh)
+ {
+ return wh->wndholder_wantAutoFocus();
+ }
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------------------------
+int WaOsWndHost::onMouseWheelUp(int click, int lines)
+{
+ return 1;
+}
+
+//-----------------------------------------------------------------------------------------------
+int WaOsWndHost::onMouseWheelDown(int click, int lines)
+{
+ return 1;
+}
+
+//-----------------------------------------------------------------------------------------------
+void VideoLayoutMonitor::hook_onResize(int x, int y, int w, int h)
+{
+ SendMessageW(wa2.getWnd(IPC_GETWND_VIDEO), WM_TIMER, 12345, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+void VideoLayoutMonitor::hook_onMove()
+{
+ SendMessageW(wa2.getWnd(IPC_GETWND_VIDEO), WM_TIMER, 12345, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+Wa2WndEmbed::Wa2WndEmbed()
+{
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<WndCallbackI*>(this));
+}
+
+//-----------------------------------------------------------------------------------------------
+Wa2WndEmbed::~Wa2WndEmbed()
+{
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<WndCallbackI*>(this));
+ wa2wndstatus.deleteAll();
+}
+
+extern int we_have_ml;
+
+//-----------------------------------------------------------------------------------------------
+int Wa2WndEmbed::testGuid(GUID g)
+{
+ if (embedWndGuidMgr.testGuid(g)) return 1;
+
+ /* if (embedWndGuids.Data2 == g.Data2 && // embed wnd check :)
+ embedWndGuids.Data3 == g.Data3 &&
+ !memcmp(embedWndGuids.Data4,g.Data4,8)) return 1;*/
+
+ return (g == pleditWndGuid || g == videoWndGuid
+#ifdef MINIBROWSER_SUPPORT
+ || g == minibrowserWndGuid
+#endif
+ || (we_have_ml && g == library_guid)
+ );
+}
+
+int make_sure_library_is_here_at_startup = 0;
+extern int m_loading_at_startup;
+
+//-----------------------------------------------------------------------------------------------
+ifc_window *Wa2WndEmbed::createWindowByGuid(GUID g, ifc_window *parent)
+{
+ if (m_loading_at_startup)
+ if (g == library_guid)
+ make_sure_library_is_here_at_startup = 1;
+ WaOsWndHost *oldhost = NULL;
+ if (embedWndGuidMgr.testGuid(g) && !embedWndGuidMgr.getEmbedWindowState(g))
+ return NULL;
+ // first check if this window is already open in a host, and if so, remove it from the wndholder
+ foreach(wndhosts)
+ if (wndhosts.getfor()->g == g)
+ {
+ WaOsWndHost *host = wndhosts.getfor()->host;
+ oldhost = host;
+ host->setTransfering(1);
+ host->oswndhost_unhost();
+ Layout *l = static_cast<Layout *>(host->getDesktopParent());
+ if (l)
+ {
+ Container *c = l->getParentContainer();
+ if (c)
+ {
+ if (!WCSCASEEQLSAFE(c->getId(), L"main"))
+ {
+ c->close(); // deferred if needed
+ }
+ else
+ {
+ softclose:
+ ifc_window *wnd = host->findWindowByInterface(windowHolderGuid);
+ if (wnd != NULL)
+ {
+ WindowHolder *wh = static_cast<WindowHolder *>(wnd->getInterface(windowHolderGuid));
+ if (wh != NULL)
+ {
+ wh->onRemoveWindow(1);
+ }
+ }
+ }
+ }
+ else goto softclose;
+ }
+ }
+ endfor;
+ // now host the wnd in a new host
+ WaOsWndHost *host = new WaOsWndHost();
+ viewer_addViewItem(host);
+ EmbedEntry *ee = new EmbedEntry();
+ wndhosts.addItem(ee);
+ ee->g = g;
+ ee->host = host;
+ ee->monitor = NULL;
+ ee->dep = host->getDependencyPtr();
+ ee->cmds = NULL;
+ if (g == pleditWndGuid)
+ {
+ RECT r = {10, 20, 5, 38};
+ host->oswndhost_setRegionOffsets(&r);
+ host->oswndhost_host(wa2.getWnd(IPC_GETWND_PE));
+ ee->whichwnd = IPC_GETWND_PE;
+ host->setName((L"Playlist Editor")/*(WASABI_API_LNGSTRINGW(IDS_PLAYLIST_EDITOR)*/);
+ GuiObject *go = parent->getGuiObject();
+ PlaylistAppCmds *plEditAppCmds = new PlaylistAppCmds();
+ ee->cmds = plEditAppCmds;
+ go->guiobject_addAppCmds(plEditAppCmds);
+ plWnd = parent; //parent->getDesktopParent();
+ //ShowWindow(host->getHWND(), SW_NORMAL);
+ }
+ else if (g == videoWndGuid)
+ {
+ RECT r = {11, 20, 8, 38};
+ host->oswndhost_setRegionOffsets(&r);
+#ifdef VIDDEBUG
+ DebugString("Video : Window service creates the host\n");
+#endif
+ HWND vid = wa2.getWnd(IPC_GETWND_VIDEO);
+ host->oswndhost_host(vid);
+ ((WaOsWndHost *)host)->setNoTransparency();
+ ee->whichwnd = IPC_GETWND_VIDEO;
+ host->setName(WASABI_API_LNGSTRINGW(IDS_VIDEO));
+ ifc_window *lw = parent->getDesktopParent();
+ if (lw)
+ {
+ GuiObject *o = lw->getGuiObject();
+ if (o)
+ {
+ ee->monitor = new VideoLayoutMonitor(o->guiobject_getScriptObject());
+ }
+ }
+ SetTimer(vid, 12345, 250, NULL);
+ GuiObject *go = parent->getGuiObject();
+ VideoAppCmds *videoAppCmds = new VideoAppCmds();
+ ee->cmds = videoAppCmds;
+ go->guiobject_addAppCmds(videoAppCmds);
+ vidWnd = parent; //parent->getDesktopParent();
+ //ShowWindow(host->getHWND(), SW_NORMAL);
+#ifdef MINIBROWSER_SUPPORT
+
+ }
+ else if (g == minibrowserWndGuid)
+ {
+ RECT r = {10, 20, 5, 38};
+ host->oswndhost_setRegionOffsets(&r);
+ host->oswndhost_host(wa2.getWnd(IPC_GETWND_MB));
+ ee->whichwnd = IPC_GETWND_MB;
+ host->setName("Minibrowser");
+ GuiObject *go = parent->getGuiObject();
+ mbWnd = parent; //parent->getDesktopParent();
+ MinibrowserAppCmds *mbAppCmds = new MinibrowserAppCmds();
+ ee->cmds = mbAppCmds;
+ go->guiobject_addAppCmds(mbAppCmds);
+ //ShowWindow(host->getHWND(), SW_NORMAL);
+#endif
+
+ }
+ else if (embedWndGuidMgr.testGuid(g)) /*(embedWndGuids.Data2 == g.Data2 &&
+ embedWndGuids.Data3 == g.Data3 &&
+ !memcmp(embedWndGuids.Data4,g.Data4,8))*/
+ {
+ embedWindowState *ws = embedWndGuidMgr.getEmbedWindowState(g);
+ ASSERT(ws != NULL);
+
+ if (0 == (WS_BORDER & GetWindowLongPtrW(ws->me, GWL_STYLE)))
+ {
+ RECT r = {11, 20, 8, 14};
+ host->oswndhost_setRegionOffsets(&r);
+ }
+ else
+ host->oswndhost_setRegionOffsets(NULL);
+
+ ws->extra_data[EMBED_STATE_EXTRA_HOSTCOUNT]++;
+ ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = (intptr_t)parent; //parent->getDesktopParent();
+ ee->whichwnd = (intptr_t)ws;
+ if (ws->flags & EMBED_FLAGS_NOTRANSPARENCY) host->setNoTransparency();
+ host->oswndhost_host(ws->me);
+ wchar_t buf[512] = {0};
+ GetWindowTextW(ws->me, buf, 512);
+ host->setName(buf);
+ }
+ else
+ {
+ wndhosts.removeItem(ee);
+ delete host;
+ delete ee;
+ return NULL;
+ }
+ wa2.setOnTop(cfg_options_alwaysontop.getValueAsInt());
+ return host;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Wa2WndEmbed::testType(const wchar_t *windowtype)
+{
+ return !_wcsicmp(windowtype, BUCKETITEM_WNDTYPE) || !_wcsicmp(windowtype, L"plsc");
+}
+
+//-----------------------------------------------------------------------------------------------
+ifc_window *Wa2WndEmbed::createWindowOfType(const wchar_t *windowtype, ifc_window *parent, int n)
+{
+ if (!_wcsicmp(windowtype, BUCKETITEM_WNDTYPE))
+ {
+ switch (n)
+ {
+ case 0:
+ {
+ PlBucketItem *bi = new PlBucketItem();
+ bi->setBitmaps(L"winamp.thinger.pledit", NULL, L"winamp.thinger.pledit.hilited", L"winamp.thinger.pledit.selected");
+ bucketitems.addItem(bi);
+ return bi;
+ }
+ case 1:
+ {
+ MlBucketItem *bi = new MlBucketItem();
+ bi->setBitmaps(L"winamp.thinger.library", NULL, L"winamp.thinger.library.hilited", L"winamp.thinger.library.selected");
+ bucketitems.addItem(bi);
+ return bi;
+ }
+ case 2:
+ {
+ VidBucketItem *bi = new VidBucketItem();
+ bi->setBitmaps(L"winamp.thinger.video", NULL, L"winamp.thinger.video.hilited", L"winamp.thinger.video.selected");
+ bucketitems.addItem(bi);
+ return bi;
+ }
+ case 3:
+ {
+ VisBucketItem *bi = new VisBucketItem();
+ bi->setBitmaps(L"winamp.thinger.vis", NULL, L"winamp.thinger.vis.hilited", L"winamp.thinger.vis.selected");
+ bucketitems.addItem(bi);
+ return bi;
+ }
+ // cases must be contiguous, enumerator stops at first NULL
+#ifdef MINIBROWSER_SUPPORT
+ case 4:
+ {
+ MbBucketItem *bi = new MbBucketItem();
+ bi->setBitmaps(hInstance, IDB_MB_TAB_NORMAL, NULL, IDB_MB_TAB_HILITED, IDB_MB_TAB_SELECTED);
+ bucketitems.addItem(bi);
+ return bi;
+ }
+#endif
+ // n is enumertor, not whichwnd
+ // we also need some way for the embeddedwnd to expose at least one bitmap (ideally 3) so we can make a nice bucketitem here (this code uses a pledit icon)
+ /* default:
+ if (n > 1024)
+ {
+ EmbedBucketItem *bi = new EmbedBucketItem();
+ bi->setBitmaps(hInstance, IDB_PLEDIT_TAB_NORMAL, NULL, IDB_PLEDIT_TAB_HILITED, IDB_PLEDIT_TAB_SELECTED);
+ bucketitems.addItem(bi);
+ return bi;
+ }
+ break;*/
+ }
+ }
+ else if (!_wcsicmp(windowtype, L"plsc"))
+ {
+ switch (n)
+ {
+ case 0:
+ pldirs.addItem(new PlDirObject);
+ return pldirs.getLast();
+ }
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Wa2WndEmbed::destroyWindow(ifc_window *w)
+{
+ foreach(bucketitems)
+ Wa2BucketItem *i = bucketitems.getfor();
+ ifc_window *rw = i;
+ if (rw == w)
+ {
+ delete i;
+ return 1;
+ }
+ endfor;
+ foreach(wndhosts)
+ EmbedEntry *ee = wndhosts.getfor();
+ WaOsWndHost *x = ee->host;
+ if (WASABI_API_WND->rootwndIsValid(x))
+ {
+ ifc_window *rw = x;
+ if (rw == w)
+ {
+ ReentryFilter f(&wndMsgFilter, ee->whichwnd);
+ if (!f.mustLeave())
+ {
+ // this would hide the winamp window, which is probably not what we want to do (it should remain visible if it
+ // was visible, no?
+
+ // well, no, because we don't only run this in skin unloading, but also when a window gets destroyed (this is the wndcreation
+ // service being called to free what it created) -- this won't happen for mmd3/pledit because mmd3 has a static window for
+ // everything, which means that when you click close on it, it doesn't destroy it but hides it, so this code isn't called. but
+ // if you load another skin (ie: NonStep), and you close the pledit, it immediately reappears with the wa2 look since oswndhost_unhost
+ // reset the flags, region and parent to what they were before the window was embedded
+
+ // i think that what we need is to save which windows were visible (and their location) before switching to freeform
+ // and to restore them when we go back to wa2 mode. this will also be more consistant with the freeform behavior of
+ // remembering visible status and coordinates on a per skin basis (since otherwise freeform dockings get screwed)
+ // it also makes sense when we consider that we are going to need to remove all windowshade modes from the embedded
+ // windows when going freeform.
+
+ // see new functions: rememberVisibleWindows() and restoreVisibleWindows()
+
+ // in any case, we need to hide the window here, at least temporarily in the case of skin unloading
+ {
+ if (ee->whichwnd > 1024)
+ {
+ embedWindowState *ws = NULL;
+ //embedWindowState *ws = (embedWindowState *)ee->whichwnd;
+ HWND hHost, hContent;
+ hHost = (NULL != x) ? x->getHWND() : NULL;
+ hContent = (NULL != hHost) ? (HWND)SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)hHost, IPC_FF_GETCONTENTWND) : NULL;
+
+ if (NULL != hContent)
+ {
+ ws = (embedWindowState *)GetWindowLongPtrW(hContent, GWLP_USERDATA);
+ }
+ else
+ {
+ embedWndGuidMgr.retireEmbedWindowState((embedWindowState *)ee->whichwnd);
+ }
+
+ if (NULL != ws &&
+ !(wa2.isValidEmbedWndState(ws) && --ws->hostcount != 0))
+ {
+ if (0 != (EMBED_FLAGS_FFCALLBACK & ws->flags) &&
+ NULL != ws->callback)
+ {
+ ws->callback(ws, FFC_DESTROYEMBED, (LPARAM)w);
+ }
+
+ x->oswndhost_unhost();
+ if (wa2.isValidEmbedWndState(ws))
+ ws->wasabi_window = NULL;
+
+ if (!x->isTransfering() && wa2.isValidEmbedWndState(ws))
+ {
+ if (IsWindow(x->getHWND()))
+ {
+ SendMessageW(ws->me, WM_USER + 101, 0, 0);
+ }
+ embedWndGuidMgr.retireEmbedWindowState(ws);
+ }
+
+ }
+ }
+ else
+ {
+ if (ee->whichwnd == IPC_GETWND_VIDEO) KillTimer(wa2.getWnd(ee->whichwnd), 12345);
+ x->oswndhost_unhost();
+ if (!x->isTransfering())
+ wa2.setWindowVisible(ee->whichwnd, 0);
+#ifdef VIDDEBUG
+ if (ee->whichwnd == IPC_GETWND_VIDEO) DebugString("Video : Window service asks WA2 to close the window\n");
+#endif
+
+ }
+ }
+ }
+ wndhosts.removeItem(ee);
+
+ embedWindowState *ws = NULL;
+ HWND thiswnd = NULL;
+ if (ee->whichwnd > 1024)
+ {
+ if (IsWindow(x->getHWND()))
+ thiswnd = x->getHWND();
+ //ws=(embedWindowState *)ee->whichwnd;
+ //thiswnd=ws->me;
+ }
+ else thiswnd = wa2.getWnd(ee->whichwnd);
+ //moved to xuioswndhost
+ //SetWindowLong(thiswnd,GWL_STYLE,GetWindowLong(thiswnd,GWL_STYLE)&~(WS_CHILDWINDOW));
+ switch (ee->whichwnd)
+ {
+ case IPC_GETWND_PE: plWnd = NULL; break;
+#ifdef MINIBROWSER_SUPPORT
+ case IPC_GETWND_MB: mbWnd = NULL; break;
+#endif
+ case IPC_GETWND_VIDEO:
+#ifdef VIDDEBUG
+ DebugString("Video : Window service destroys host\n");
+#endif
+ vidWnd = NULL;
+ break;
+ default:
+ if (ee->whichwnd > 1024 && ws && thiswnd != NULL)
+ {
+ ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = 0;
+ }
+ break;
+ }
+ if (ee->cmds)
+ {
+ GuiObject *o = w->getParent()->getGuiObject();
+ o->guiobject_removeAppCmds(ee->cmds);
+ }
+ x->oswndhost_unhost(); // ignored if already done by reentryfiltered code
+ delete ee->monitor;
+ delete ee->cmds;
+ delete x;
+
+
+ if (ee->whichwnd > 1024 && ws)
+ {
+ if (forcedoffwnds.haveItem(ws->me))
+ {
+ RECT r;
+ GetWindowRect(ws->me, &r);
+ SetWindowPos(ws->me, NULL, r.left + 20000, r.top + 20000, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOZORDER);
+ forcedoffwnds.delItem(ws->me);
+ }
+ }
+ delete ee;
+ SetFocus(wa2.getMainWindow());
+
+ return 1;
+ }
+ endfor;
+ foreach (pldirs)
+ PlDirObject *pldir = pldirs.getfor();
+ if (pldir == w)
+ {
+ delete pldir;
+ return 1;
+ }
+ endfor;
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Wa2WndEmbed::viewer_onEvent(ifc_window *item, int event, intptr_t param, void *ptr, size_t ptrlen)
+{
+ if (event == ifc_window::Event_SETVISIBLE)
+ {
+ /* if (!param) {
+ // the wnd may be going away, but then again, it might just be hidden to show an alternate layout of the same
+ // container, so before continuing, we need to check if it's actually going away. There is of course an exception
+ // in that if the window is hosted by a wndholder with autoclose="1", we should mirror the hiding state regardless
+ // of the container state
+
+ api_window *whr = item->getParent();
+ int except = 0;
+ if (whr) {
+ GuiObject *go = whr->getGuiObject();
+ if (go) {
+ const char *par = go->guiobject_getXmlParam("autoclose");
+ if (!par || (par && ATOI(par) == 1)) except = 1;
+ }
+ }
+ if (!except) {
+ api_window *lr = item->getDesktopParent();
+ if (lr) {
+ Layout *l = static_cast<Layout *>(lr->getInterface(layoutGuid));
+ if (l) {
+ Container *c = l->getParentContainer();
+ if (c) {
+ if (c->isVisible()) return 1;
+ }
+ }
+ }
+ }
+ }*/
+ foreach(wndhosts)
+ EmbedEntry *ee = wndhosts.getfor();
+ XuiOSWndHost *x = ee->host;
+ ifc_window *rw = x;
+ if (rw == item)
+ {
+ {
+ ReentryFilter f(&wndMsgFilter, ee->whichwnd);
+ if (f.mustLeave()) continue;
+ }
+ if (ee->whichwnd > 1024)
+ {
+ embedWindowState *ws = (embedWindowState *)ee->whichwnd;
+ if (!param && wa2.isValidEmbedWndState(ws))
+ {
+ if (IsWindow(ws->me))
+ SendMessageW(ws->me, WM_USER + 101, 0, 0);
+ ifc_window *rwh = x->findWindowByInterface(windowHolderGuid);
+ if (rwh != NULL)
+ {
+ WindowHolder *wh = static_cast<WindowHolder *>(rwh->getInterface(windowHolderGuid));
+ if (wh != NULL)
+ {
+ wh->onRemoveWindow(1);
+ }
+ }
+ if (wa2.isValidEmbedWndState(ws)) ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = NULL;
+ }
+ else if (wa2.isValidEmbedWndState(ws))
+ {
+ ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = (intptr_t)item->getParent();
+ ShowWindow(ws->me, SW_NORMAL);
+ }
+ }
+ else
+ {
+ ReentryFilter f(&wndMsgFilter, ee->whichwnd);
+#ifdef VIDDEBUG
+ if (ee->whichwnd == IPC_GETWND_VIDEO && param != wa2.isWindowVisible(ee->whichwnd)) DebugString("Video : Detected that the host is %s, syncing\n", param ? "shown" : "hidden");
+#endif
+ wa2.setWindowVisible(ee->whichwnd, param);
+ }
+ }
+ endfor;
+ }
+ return 1;
+}
+
+int Wa2WndEmbed::onShowWindow(Container *c, GUID guid, const wchar_t *groupid)
+{
+ foreach(wndhosts)
+ EmbedEntry *ee = wndhosts.getfor();
+ if (ee->g == guid)
+ {
+ ReentryFilter f(&wndMsgFilter, ee->whichwnd);
+ if (f.mustLeave()) return 1;
+ if (guid == videoWndGuid) wa2.setWindowVisible(IPC_GETWND_VIDEO, 1);
+#ifdef MINIBROWSER_SUPPORT
+ else if (guid == minibrowserWndGuid) wa2.setWindowVisible(IPC_GETWND_MB, 1);
+#endif
+ else if (guid == pleditWndGuid) wa2.setWindowVisible(IPC_GETWND_PE, 1);
+ }
+ endfor;
+ return 1;
+}
+
+int Wa2WndEmbed::onHideWindow(Container *c, GUID guid, const wchar_t *groupid)
+{
+ /* if (guid == INVALID_GUID) return 1;
+ embedWindowState *ws = embedWndGuidMgr.getEmbedWindowState(guid);
+ if (ws != NULL && wa2.isValidEmbedWndState(ws)) {
+ if (IsWindow(ws->me))
+ SendMessageW(ws->me,WM_USER+101,0,0);
+ api_window *x = (api_window*)ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND];
+ if (x && WASABI_API_WND->rootwndIsValid(x)) {
+ api_window *rwh = x->findWindowByInterface(windowHolderGuid);
+ if (rwh != NULL) {
+ WindowHolder *wh = static_cast<WindowHolder *>(rwh->getInterface(windowHolderGuid));
+ if (wh != NULL) {
+ wh->onRemoveWindow(1);
+ }
+ }
+ }
+ ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = NULL;
+ }
+ */
+ foreach(wndhosts)
+ EmbedEntry *ee = wndhosts.getfor();
+ if (ee->g == guid)
+ {
+ ReentryFilter f(&wndMsgFilter, ee->whichwnd);
+ if (f.mustLeave()) return 1;
+ if (ee->host->isTransfering()) return 1;
+ ifc_window *dp = ee->host->getDesktopParent();
+ if (dp)
+ {
+ Layout *l = static_cast<Layout*>(dp->getInterface(layoutGuid));
+ if (l)
+ {
+ if (l->getParentContainer() != c) return 1;
+ }
+ }
+ if (guid == videoWndGuid) wa2.setWindowVisible(IPC_GETWND_VIDEO, 0);
+#ifdef MINIBROWSER_SUPPORT
+ else if (guid == minibrowserWndGuid) wa2.setWindowVisible(IPC_GETWND_MB, 0);
+#endif
+ else if (guid == pleditWndGuid) wa2.setWindowVisible(IPC_GETWND_PE, 0);
+ }
+ endfor;
+
+ return 1;
+}
+
+extern wchar_t *INI_FILE;
+
+int Wa2WndEmbed::embedRememberProc(embedWindowState *p, embedEnumStruct *parms)
+{
+ WndStatus *ws = new WndStatus;
+ ws->wndcode = -1; // if you insert a wnd that is not in embedTable, put -1 as wndcode
+ ws->wnd = p->me;
+ ws->visible = IsWindowVisible(p->me);
+ GetWindowRect(p->me, &ws->position);
+ // ws->position=p->r;
+ wa2wndstatus.addItem(ws);
+
+ // only store the ml window position if not loading on startup
+ if(going_freeform && !m_loading_at_startup)
+ {
+ HWND mlwnd = wa2.getMediaLibrary();
+ if(GetWindow(p->me, GW_CHILD) == mlwnd)
+ {
+ WritePrivateProfileStringW(L"gen_ff", L"classicmlwidth", StringPrintfW(L"%d", ws->position.right - ws->position.left), INI_FILE);
+ WritePrivateProfileStringW(L"gen_ff", L"classicmlheight", StringPrintfW(L"%d", ws->position.bottom - ws->position.top), INI_FILE);
+ }
+ }
+ return 0;
+}
+
+extern int m_loading_at_startup;
+
+//-----------------------------------------------------------------------------------------------
+// todo: remember and restore windowshade modes
+void Wa2WndEmbed::rememberVisibleWindows()
+{
+ wa2wndstatus.deleteAll();
+ for (int i = 0;i < sizeof(embedTable) / sizeof(embedTable[0]);i++)
+ {
+ HWND w = wa2.getWnd(embedTable[i]);
+ WndStatus *ws = new WndStatus;
+ ws->wndcode = embedTable[i]; // if you insert a wnd that is not in embedTable, put -1 as wndcode
+ ws->wnd = w;
+ ws->visible = wa2.isWindowVisible(embedTable[i]);
+ GetWindowRect(w, &ws->position);
+ if (going_freeform)
+ {
+ if (embedTable[i] == IPC_GETWND_PE)
+ {
+ int peheight = ws->position.bottom - ws->position.top;
+ int pewidth = ws->position.right - ws->position.left;
+ if (!m_loading_at_startup)
+ {
+ WritePrivateProfileStringW(L"gen_ff", L"classicplwidth", StringPrintfW(L"%d", pewidth), INI_FILE);
+ WritePrivateProfileStringW(L"gen_ff", L"classicplheight", StringPrintfW(L"%d", peheight), INI_FILE);
+ }
+ int classicpews = wa2.isWindowShade(IPC_GETWND_PE);
+ if (!m_loading_at_startup || GetPrivateProfileIntW(L"gen_ff", L"classicplws", -1, INI_FILE) == -1)
+ WritePrivateProfileStringW(L"gen_ff", L"classicplws", classicpews ? L"1" : L"0", INI_FILE);
+ if (classicpews)
+ SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_OPTIONS_WINDOWSHADE_PL, 0);
+ GetWindowRect(w, &ws->position);
+ }
+ }
+ wa2wndstatus.addItem(ws);
+ }
+ embedEnumStruct cs = { embedRememberProc, 0};
+ SendMessageW(wa2.getMainWindow(), WM_WA_IPC, (WPARAM)&cs, IPC_EMBED_ENUM);
+}
+
+int Wa2WndEmbed::hadRememberedWndVisible(HWND w)
+{
+ int n = wa2wndstatus.getNumItems();
+ for (int i = 0;i < n;i++)
+ {
+ WndStatus *ws = wa2wndstatus.enumItem(i);
+ if (ws->wnd == w && ws->visible)
+ return 1;
+ }
+ return 0;
+}
+
+void Wa2WndEmbed::restoreVisibleWindows()
+{
+ int n = wa2wndstatus.getNumItems();
+ HWND mlwnd = wa2.getMediaLibrary();
+ for (int i = 0;i < n;i++)
+ {
+ WndStatus *ws = wa2wndstatus.enumItem(i);
+ if (going_fixedform && !m_loading_at_startup)
+ {
+ if (embedTable[i] == IPC_GETWND_PE)
+ {
+ int classicpews = GetPrivateProfileIntW(L"gen_ff", L"classicplws", 0, INI_FILE);
+ if (classicpews)
+ {
+ SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_OPTIONS_WINDOWSHADE_PL, 0);
+ }
+ int classicwidth = GetPrivateProfileIntW(L"gen_ff", L"classicplwidth", 275, INI_FILE);
+ int classicheight = GetPrivateProfileIntW(L"gen_ff", L"classicplheight", 145, INI_FILE);
+ wa2.setPlEditWidthHeight(classicwidth, classicheight);
+ }
+
+ if(GetWindow(ws->wnd, GW_CHILD) == mlwnd)
+ {
+ // only restore the ml window size if we were able to read in saved values
+ int mlwidth = GetPrivateProfileIntW(L"gen_ff", L"classicmlwidth", -1, INI_FILE);
+ int mlheight = GetPrivateProfileIntW(L"gen_ff", L"classicmlheight", -1, INI_FILE);
+ if(mlwidth != -1 && mlheight != -1)
+ SetWindowPos(ws->wnd, 0, 0, 0, mlwidth, mlheight, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
+ }
+ }
+ // FG> as of oct19, this function only restores state for windows that WERE visible
+ // because there is no reason to hide one, since this function is designed to bring
+ // back those windows that were here in one mode, but aren't so anymore in another
+ if (ws->visible)
+ {
+ if (ws->wndcode != -1)
+ {
+ wa2.setWindowVisible(ws->wndcode, ws->visible);
+ }
+ else
+ {
+ ShowWindow(ws->wnd, ws->visible ? SW_SHOWNA : SW_HIDE);
+ }
+ }
+ }
+}
+
+PtrList<WndStatus> Wa2WndEmbed::wa2wndstatus;
+
+//-----------------------------------------------------------------------------------------------
+PlaylistAppCmds::PlaylistAppCmds()
+: addCmd(L"Add", PL_ADD, AppCmds::SIDE_LEFT, 0),
+ remCmd(L"Rem", PL_REM, AppCmds::SIDE_LEFT, 0),
+ selCmd(L"Sel", PL_SEL, AppCmds::SIDE_LEFT, 0),
+ miscCmd(L"Misc", PL_MISC, AppCmds::SIDE_LEFT, 0),
+ listCmd(L"List", PL_LIST, AppCmds::SIDE_RIGHT, 0)
+{
+ appcmds_addCmd(&addCmd);
+ appcmds_addCmd(&remCmd);
+ appcmds_addCmd(&selCmd);
+ appcmds_addCmd(&miscCmd);
+ appcmds_addCmd(&listCmd);
+}
+
+void PlaylistAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
+{
+ switch (id)
+ {
+ case PL_ADD:
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_ADD, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
+ break;
+ case PL_REM:
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_REM, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
+ break;
+ case PL_SEL:
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_SEL, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
+ break;
+ case PL_MISC:
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_MISC, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
+ break;
+ case PL_LIST:
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_LIST, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
+ break;
+ }
+}
+
+
+#ifdef MINIBROWSER_SUPPORT
+//-----------------------------------------------------------------------------------------------
+MinibrowserAppCmds::MinibrowserAppCmds()
+{
+ appcmds_addCmd(new CmdRec("Back", MB_BACK, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec("Forward", MB_FORWARD, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec("Stop", MB_STOP, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec("Reload", MB_RELOAD, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec("Misc", MB_MISC, AppCmds::SIDE_RIGHT, 1));
+}
+
+void MinibrowserAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
+{
+ switch (id)
+ {
+ case MB_BACK:
+ wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_BACK);
+ break;
+ case MB_FORWARD:
+ wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_FORWARD);
+ break;
+ case MB_STOP:
+ wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_STOP);
+ break;
+ case MB_RELOAD:
+ wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_RELOAD);
+ break;
+ case MB_MISC:
+ wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBPOPUP_MISC, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
+ break;
+ }
+}
+#endif
+
+//-----------------------------------------------------------------------------------------------
+VideoAppCmds::VideoAppCmds()
+{
+ appcmds_addCmd(new CmdRec(L"Fullscreen", VID_FULLSCREEN, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec(L"1x", VID_1X, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec(L"2x", VID_2X, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec(L"TV", VID_LIB, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec(L"Misc", VID_MISC, AppCmds::SIDE_RIGHT, 1));
+}
+
+void VideoAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
+{
+ switch (id)
+ {
+ case VID_FULLSCREEN:
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_FULLSCREEN);
+ break;
+ case VID_1X:
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_1X);
+ break;
+ case VID_2X:
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_2X);
+ break;
+ case VID_LIB:
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_LIB);
+ break;
+ case VID_MISC:
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDPOPUP_MISC, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
+ break;
+ }
+}
+
diff --git a/Src/Plugins/General/gen_ff/wa2wndembed.h b/Src/Plugins/General/gen_ff/wa2wndembed.h
new file mode 100644
index 00000000..f50501c7
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2wndembed.h
@@ -0,0 +1,223 @@
+#ifndef __WA2WNDEMBED_H
+#define __WA2WNDEMBED_H
+
+#include "../winamp/wa_ipc.h"
+#include <api/service/svcs/svc_wndcreate.h>
+#include <bfc/depview.h>
+#include <bfc/reentryfilter.h>
+#include <api/wndmgr/appcmds.h>
+#include <api/skin/widgets/xuioswndhost.h>
+#include <api/script/objects/c_script/h_layout.h>
+#include <api/syscb/callbacks/wndcb.h>
+#include "wa2pldirobj.h"
+
+class BucketItem;
+class XuiOSWndHost;
+class Wa2BucketItem;
+
+#define EMBED_STATE_EXTRA_LINK 0
+#define EMBED_STATE_EXTRA_ATTACHED 1
+#define EMBED_STATE_EXTRA_HOSTCOUNT 61
+#define EMBED_STATE_EXTRA_REPARENTING 62
+#define EMBED_STATE_EXTRA_FFROOTWND 63
+
+//-----------------------------------------------------------------------------------------------
+// {E6323F86-1724-4cd3-9D87-70591FC16E5E}
+static const GUID playerWndGuid =
+{ 0xe6323f86, 0x1724, 0x4cd3, { 0x9d, 0x87, 0x70, 0x59, 0x1f, 0xc1, 0x6e, 0x5e } };
+// benski> don't use this in a windowholder, this is for <container primarycontent="guid:main"/>
+
+
+//-----------------------------------------------------------------------------------------------
+// {45F3F7C1-A6F3-4ee6-A15E-125E92FC3F8D}
+static const GUID pleditWndGuid =
+{ 0x45f3f7c1, 0xa6f3, 0x4ee6, { 0xa1, 0x5e, 0x12, 0x5e, 0x92, 0xfc, 0x3f, 0x8d } };
+
+//-----------------------------------------------------------------------------------------------
+// {F0816D7B-FFFC-4343-80F2-E8199AA15CC3}
+static const GUID videoWndGuid =
+{ 0xf0816d7b, 0xfffc, 0x4343, { 0x80, 0xf2, 0xe8, 0x19, 0x9a, 0xa1, 0x5c, 0xc3 } };
+
+#ifdef MINIBROWSER_SUPPORT
+
+//-----------------------------------------------------------------------------------------------
+// {CF477C3E-FDC8-44a2-9066-58D0184D47A8}
+static const GUID minibrowserWndGuid =
+{ 0xcf477c3e, 0xfdc8, 0x44a2, { 0x90, 0x66, 0x58, 0xd0, 0x18, 0x4d, 0x47, 0xa8 } };
+
+#endif
+// scan
+static const GUID embedWndGuids =
+{ 0x00000000, 0xf000, 0x44a2, { 0x90, 0x66, 0x58, 0xd0, 0x18, 0x4d, 0x47, 0xa8 } };
+
+// {A8533CEC-D05D-45b8-A617-E2B7F2C2CF82}
+static const GUID embeddedWndStateGuid =
+{ 0xa8533cec, 0xd05d, 0x45b8, { 0xa6, 0x17, 0xe2, 0xb7, 0xf2, 0xc2, 0xcf, 0x82 } };
+
+// {6B0EDF80-C9A5-11d3-9F26-00C04F39FFC6}
+static const GUID library_guid =
+{ 0x6b0edf80, 0xc9a5, 0x11d3, { 0x9f, 0x26, 0x0, 0xc0, 0x4f, 0x39, 0xff, 0xc6 } };
+
+// {B397A4CE-455A-4d62-8BF6-D0F91ACB70E6}
+static const GUID preferences_guid =
+{ 0xb397a4ce, 0x455a, 0x4d62, { 0x8b, 0xf6, 0xd0, 0xf9, 0x1a, 0xcb, 0x70, 0xe6 } };
+
+// {0000000A-000C-0010-FF7B-01014263450C}
+static const GUID avs_guid =
+{ 10, 12, 16, { 255, 123, 1, 1, 66, 99, 69, 12 } };
+
+// {8DDA9D48-B915-4320-A888-831A1D837516}
+static const GUID about_guid =
+{ 0x8dda9d48, 0xb915, 0x4320, { 0xa8, 0x88, 0x83, 0x1a, 0x1d, 0x83, 0x75, 0x16 } };
+
+// {D6201408-476A-4308-BF1B-7BACA1124B12}
+static const GUID lightning_bolt_guid =
+{ 0xd6201408, 0x476a, 0x4308, { 0xbf, 0x1b, 0x7b, 0xac, 0xa1, 0x12, 0x4b, 0x12 } };
+
+// {53DE6284-7E88-4c62-9F93-22ED68E6A024}
+static const GUID colorthemes_guid =
+{ 0x53de6284, 0x7e88, 0x4c62, { 0x9f, 0x93, 0x22, 0xed, 0x68, 0xe6, 0xa0, 0x24 } };
+
+
+//-----------------------------------------------------------------------------------------------
+class WaOsWndHost : public XuiOSWndHost
+{
+ public:
+ WaOsWndHost() : transparencysafe(1), transfer(0) {}
+ virtual void onBeforeReparent(int i);
+ virtual void onAfterReparent(int i);
+ virtual int wantHideOnUnhost() { return 1; }
+ virtual int wantFocus();
+ virtual int onGetFocus();
+ virtual int handleTransparency() { return transparencysafe; }
+ virtual void setNoTransparency() { transparencysafe = 0; }
+ void setTransfering(int i) { transfer = i; }
+ int isTransfering() { return transfer; }
+ virtual int onMouseWheelUp(int click, int lines);
+ virtual int onMouseWheelDown(int click, int lines);
+ private:
+ int transparencysafe;
+ int transfer;
+};
+
+//-----------------------------------------------------------------------------------------------
+class VideoLayoutMonitor : public H_Layout
+{
+ public:
+ VideoLayoutMonitor(ScriptObject *o) : H_Layout(o) { }
+ VideoLayoutMonitor() {}
+ virtual void hook_onResize(int x, int y, int w, int h);
+ virtual void hook_onMove();
+};
+
+//-----------------------------------------------------------------------------------------------
+class EmbedEntry
+{
+ public:
+ WaOsWndHost *host;
+ ifc_dependent *dep;
+ intptr_t whichwnd;
+ AppCmds *cmds;
+ VideoLayoutMonitor *monitor;
+ GUID g;
+};
+
+class WndStatus
+{
+ public:
+ int wndcode; // or -1
+ HWND wnd;
+ int visible;
+ RECT position;
+};
+
+//-----------------------------------------------------------------------------------------------
+class Wa2WndEmbed : public svc_windowCreateI, DependentViewerTPtr<ifc_window>, public WndCallbackI
+{
+ public:
+ Wa2WndEmbed();
+ virtual ~Wa2WndEmbed();
+
+ static const char *getServiceName() { return "Playlist Editor window creator"; }
+
+ virtual int testGuid(GUID g);
+ virtual ifc_window *createWindowByGuid(GUID g, ifc_window *parent);
+ virtual int testType(const wchar_t *windowtype);
+ virtual ifc_window *createWindowOfType(const wchar_t *windowtype, ifc_window *parent, int n);
+ virtual int destroyWindow(ifc_window *w);
+ virtual int viewer_onEvent(ifc_window *item, int event, intptr_t param, void *ptr, size_t ptrlen);
+
+ static void rememberVisibleWindows();
+ static void restoreVisibleWindows();
+ static int hadRememberedWndVisible(HWND wnd);
+ static int embedRememberProc(embedWindowState *p, embedEnumStruct *parms);
+
+ virtual int onShowWindow(Container *c, GUID guid, const wchar_t *groupid);
+ virtual int onHideWindow(Container *c, GUID guid, const wchar_t *groupid);
+
+ PtrList<Wa2BucketItem> bucketitems;
+ PtrList<EmbedEntry> wndhosts;
+ PtrList<PlDirObject> pldirs;
+ static PtrList<WndStatus> wa2wndstatus;
+ static int switching_holder;
+
+};
+
+extern ReentryFilterObject wndMsgFilter;
+
+//-----------------------------------------------------------------------------------------------
+class PlaylistAppCmds : public AppCmdsI
+{
+ public:
+ PlaylistAppCmds();
+ virtual ~PlaylistAppCmds() {}
+ virtual void appcmds_onCommand(int id, const RECT *buttonRect, int which_button);
+
+ enum {
+ PL_ADD=0,
+ PL_REM,
+ PL_SEL,
+ PL_MISC,
+ PL_LIST,
+ };
+
+protected:
+ CmdRec addCmd, remCmd, selCmd, miscCmd, listCmd;
+};
+
+#ifdef MINIBROWSER_SUPPORT
+
+//-----------------------------------------------------------------------------------------------
+class MinibrowserAppCmds : public AppCmdsI {
+ public:
+ MinibrowserAppCmds();
+ virtual ~MinibrowserAppCmds() {}
+ virtual void appcmds_onCommand(int id, const RECT *buttonRect, int which_button);
+
+ enum {
+ MB_BACK=0,
+ MB_FORWARD,
+ MB_STOP,
+ MB_RELOAD,
+ MB_MISC,
+ };
+};
+#endif
+
+//-----------------------------------------------------------------------------------------------
+class VideoAppCmds : public AppCmdsI {
+ public:
+ VideoAppCmds();
+ virtual ~VideoAppCmds() {}
+ virtual void appcmds_onCommand(int id, const RECT *buttonRect, int which_button);
+
+ enum {
+ VID_FULLSCREEN=0,
+ VID_1X,
+ VID_2X,
+ VID_LIB,
+ VID_MISC,
+ };
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/General/gen_ff/wasabi.dsp b/Src/Plugins/General/gen_ff/wasabi.dsp
new file mode 100644
index 00000000..e2db5c47
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wasabi.dsp
@@ -0,0 +1,1931 @@
+# Microsoft Developer Studio Project File - Name="wasabi" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=wasabi - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "wasabi.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "wasabi.mak" CFG="wasabi - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "wasabi - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "wasabi - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "wasabi - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "_build/Release"
+# PROP Intermediate_Dir "_build/Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zd /O2 /I "../gen_ff" /I "../wasabi" /I "../wasabi/api/font/freetype/freetype2/include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Yu"precomp.h" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "wasabi - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "_build/Debug"
+# PROP Intermediate_Dir "_build/Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../gen_ff" /I "../wasabi" /I "../wasabi/api/font/freetype/freetype2/include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /Yu"precomp.h" /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "wasabi - Win32 Release"
+# Name "wasabi - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Group "system"
+
+# PROP Default_Filter ""
+# Begin Group "file"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\file\filename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\file\readdir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\file\recursedir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\file\wildcharsenum.cpp
+# End Source File
+# End Group
+# Begin Group "memory"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\foreach.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\freelist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\loadlib.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\memblock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\ptrlist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\stack.cpp
+# End Source File
+# End Group
+# Begin Group "utils"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\util\profiler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\util\timefmt.cpp
+# End Source File
+# End Group
+# Begin Group "string"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\string\bigstring.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\string\encodedstr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\string\playstring.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Wasabi\bfc\string\string.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\string\url.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\string\utf8.cpp
+# End Source File
+# End Group
+# Begin Group "parse"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\parse\hierarchyparser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\parse\paramparser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\parse\pathparse.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\assert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\critsec.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\depend.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\node.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\nsGUID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\std.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\std_file.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\std_math.cpp
+# End Source File
+# End Group
+# Begin Group "apis"
+
+# PROP Default_Filter ""
+# Begin Group "svc"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\api_service.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\api_servicei.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\api_servicex.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\syscb\callbacks\consolecb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\servicei.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svc_enum.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svccache.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcenum.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcenumbyguid.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcenumt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcmgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\waservicefactory.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\waservicefactorybase.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\waservicefactoryi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\waservicefactoryt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\waservicefactorytsingle.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\waservicefactoryx.cpp
+# End Source File
+# End Group
+# Begin Group "wnd"
+
+# PROP Default_Filter ""
+# Begin Group "wndclass"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\abstractwndhold.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\appbarwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\backbufferwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\basewnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\blankwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\bufferpaintwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\buttbar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\buttwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\clickwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\editwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\editwndstring.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\embeddedxui.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\foreignwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\framewnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\gradientwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\guiobjwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\labelwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\listwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\oswnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\oswndhost.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\paintset.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\qpaintwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\rootwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\rootwndholder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\scbkgwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\scrollbar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\sepwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\slider.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\status.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\svcwndhold.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\tooltip.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\treewnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\typesheet.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\virtualwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\wndholder.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\api_wnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\autobitmap.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\bitmap.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\blending.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\contextmenu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\cursor.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\deactivatemgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\dragitemi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\filteredcolor.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\findobjectcb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\util\findopenrect.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\keyboard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\paintcb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\popexitcb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\popexitchecker.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\popup.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\std_wnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcs\svc_wndcreate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\timer\timerclient.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\platform\win32\win32_canvas.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\platform\win32\win32_region.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndapi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\syscb\callbacks\wndcb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndtrack.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\xmlobject.cpp
+# End Source File
+# End Group
+# Begin Group "timer"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\timer\api_timer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\timer\genwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\timer\timerapi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\timer\timermul.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\timer\tmultiplex.cpp
+# End Source File
+# End Group
+# Begin Group "app"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\application\api_application.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\application\api_applicationi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\application\api_applicationx.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wac\\compon.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\util\inifile.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\application\pathmgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\application\version.cpp
+# End Source File
+# End Group
+# Begin Group "font"
+
+# PROP Default_Filter ""
+# Begin Group "freetype"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\font\freetype\freetype.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\font\freetype\freetypefont.cpp
+# End Source File
+# End Group
+# Begin Group "win32"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\font\win32\truetypefont_win32.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\api\font\api_font.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\font\bitmapfont.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\font\font.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\font\fontapi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcs\svc_font.cpp
+# End Source File
+# End Group
+# Begin Group "syscb"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\syscb\api_syscb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\syscb\api_syscbi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\syscb\api_syscbx.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\syscb\cbmgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\syscb\callbacks\syscb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\syscb\callbacks\syscbi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\syscb\callbacks\syscbx.cpp
+# End Source File
+# End Group
+# Begin Group "imgldr"
+
+# PROP Default_Filter ""
+# Begin Group "pngload"
+
+# PROP Default_Filter ""
+# Begin Group "pnglib"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\pngload\pnglib\PNG.C
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\pngload\pnglib\PNGERROR.C
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\pngload\pnglib\PNGGET.C
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\pngload\pnglib\PNGMEM.C
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\pngload\pnglib\PNGREAD.C
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\pngload\pnglib\PNGRIO.C
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\pngload\pnglib\PNGRTRAN.C
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\pngload\pnglib\PNGRUTIL.C
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\pngload\pnglib\PNGSET.C
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\pngload\pnglib\PNGTRANS.C
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\pngload\loader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\pngload\pngload.cpp
+# End Source File
+# End Group
+# Begin Group "jpgload"
+
+# PROP Default_Filter ""
+# Begin Group "jpgdlib"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\jpgload\jpgdlib\H2v2.cpp
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\jpgload\jpgdlib\idct.cpp
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\jpgload\jpgdlib\jidctfst.cpp
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\jpgload\jpgdlib\jpegdecoder.cpp
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\jpgload\jpgdlib\jpegdecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\jpgload\jpgdlib\jpegdecoder.inl
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\jpgload\jpgdlib\main.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\jpgload\jpgload.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\jpgload\loader_jpg.cpp
+# End Source File
+# End Group
+# Begin Group "imggen"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\draw\drawpoly.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\imggen\grad.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\imggen\osedge.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\imggen\poly.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\imggen\solid.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcs\svc_imggen.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\api_imgldr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\imgldr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\imgldr\imgldrapi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcs\svc_imgload.cpp
+# End Source File
+# End Group
+# Begin Group "ffskin"
+
+# PROP Default_Filter ""
+# Begin Group "widgets"
+
+# PROP Default_Filter ""
+# Begin Group "tooltips"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\grouptips.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcs\svc_tooltips.cpp
+# End Source File
+# End Group
+# Begin Group "mb"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\mb\Atl.cpp
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\mb\iebrowser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\mb\mbsvc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcs\svc_minibrowser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\mb\xuibrowser.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\animlayer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\button.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\checkbox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\combobox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\compbuck2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\customobject.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\dropdownlist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\edit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\feeds\feedwatch.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\feeds\feedwatcherso.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\fx_dmove.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\bfc\draw\gradient.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\group.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\groupclickwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\grouplist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\grouptgbutton.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\guiradiogroup.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\guistatuscb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\historyeditbox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\layer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\mb\mainminibrowser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\mb\minibrowser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\mb\minibrowserwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\mouseredir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\nakedobject.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\objdirwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\objectactuator.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\pathpicker.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\pslider.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\sa.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\seqband.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\seqpreamp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\seqvis.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\spanbar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\sseeker.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\sstatus.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcs\svc_xuiobject.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\svolbar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\tabsheet.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wnd\wndclass\tabsheetbar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\text.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\tgbutton.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\title.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\titlebox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuiaddparams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuibookmarklist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuicheckbox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuicombobox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuicustomobject.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuidropdownlist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuieditbox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuiframe.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuigradientwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuigrid.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuigroupxfade.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuihideobject.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuihistoryedit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuilist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuimenu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuimenuso.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuiobjdirwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuioswndhost.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuipathpicker.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuiprogressgrid.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuiradiogroup.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuirect.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuisendparams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuistatus.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuitabsheet.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuithemeslist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuititlebox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuitree.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\xuiwndholder.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\api_skin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\cursormgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\gammamgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\groupmgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\groupwndcreate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\guitree.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\regioncache.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\skin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\skinapi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\syscb\callbacks\skincb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\skinclr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\skinelem.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\skinfilter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\skinfont.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\skinitem.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\skinparse.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcs\svc_skinfilter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcs\svc_textfeed.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\feeds\textfeed.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets.cpp
+# End Source File
+# End Group
+# Begin Group "xml"
+
+# PROP Default_Filter ""
+# Begin Group "parser"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\xml\parser\hashtable.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\xml\parser\simap.cpp
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\xml\parser\xmlparser.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\xml\parser\xmlrole.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\xml\parser\xmltok.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\api\xml\api_xml.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\xml\xmlapi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\xml\xmlparams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\xml\xmlparamsi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\xml\xmlparamsx.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\xml\xmlreader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\xml\xmlwrite.cpp
+# End Source File
+# End Group
+# Begin Group "script"
+
+# PROP Default_Filter ""
+# Begin Group "maki"
+
+# PROP Default_Filter ""
+# Begin Group "maki classes"
+
+# PROP Default_Filter ""
+# Begin Group "encapsulators"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\rootobj.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\rootobjcb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\rootobjcbi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\rootobjcbx.cpp
+# End Source File
+# End Group
+# Begin Group "c_script"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_browser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_button.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_checkbox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_container.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_dropdownlist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_edit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_group.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_guilist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_guiobject.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_guitree.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_layout.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_menubutton.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_querylist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_rootobj.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_slider.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_text.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_togglebutton.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\c_treeitem.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_browser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_button.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_checkbox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_container.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_dropdownlist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_edit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_group.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_guilist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_guiobject.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_guitree.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_layout.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_menubutton.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_querylist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_rootobj.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_slider.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_text.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_togglebutton.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\h_treeitem.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\c_script\scripthook.cpp
+# End Source File
+# End Group
+# Begin Group "scriptcore"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\core\coreadminobj.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\core\coreobj.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\core\svc_scriptcore.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\guiobj.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objcontrollert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\rootobjcontroller.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\rootobject.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\rootobjecti.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\rootobjectx.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\sbitlist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\slist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\smap.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\spopup.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\sregion.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\systemobj.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\timer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objects\wacobj.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\guru.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objcontroller.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\objecttable.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\script.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\scriptmgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\scriptobj.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\scriptobji.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\scriptobjx.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\vcpu.cpp
+# End Source File
+# End Group
+# Begin Group "debugger"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\debugger\api_makidebug.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\debugger\debugapi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\debugger\debuggerui.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\debugger\debugsymbols.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\debugger\disasm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\debugger\jitd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\debugger\jitdbreak.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\debugger\sdebuggerui.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\debugger\sourcecodeline.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\debugger\vcpudebug.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\api_maki.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\api_makii.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\script\api_makix.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcs\svc_scriptobj.cpp
+# End Source File
+# End Group
+# Begin Group "wndmgr"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\alphamgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\animate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\api_wndmgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\appcmds.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\autopopup.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\container.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\gc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\layout.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\msgbox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\resize.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\skinembed.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\skinwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\snappnt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\wndmgr\wndmgrapi.cpp
+# End Source File
+# End Group
+# Begin Group "core"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\core\api_core.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\syscb\callbacks\corecb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcs\svc_action.cpp
+# End Source File
+# End Group
+# Begin Group "filereaders"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\filereader\api_filereader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\filereader\local\fileread.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\filereader\\filereaderapi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\filereader\res\resread.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\service\svcs\svc_fileread.cpp
+# End Source File
+# End Group
+# Begin Group "cfg"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\config\api_config.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\config\api_configi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\config\api_configx.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\config\items\attribute.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\config\items\attrstr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\config\items\cfgitemi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api/config\cfglist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\config\cfgscriptobj.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\config\config.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\config\items\intarray.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\config\options.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\config\uioptions.cpp
+# End Source File
+# End Group
+# Begin Group "locales"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\locales\api_locales.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\locales\api_localesi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\locales\api_localesx.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\locales\localesmgr.cpp
+# End Source File
+# End Group
+# Begin Group "memmgr"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\memmgr\api_memmgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\memmgr\memmgrapi.cpp
+# End Source File
+# End Group
+# Begin Group "util"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\util\selectfile.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\util\systray.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\util\varmgr.cpp
+# End Source File
+# End Group
+# End Group
+# Begin Group "debug"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\stats\statswnd.cpp
+
+!IF "$(CFG)" == "wasabi - Win32 Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "wasabi - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\wasabi\api\skin\widgets\stats\xuistats.cpp
+
+!IF "$(CFG)" == "wasabi - Win32 Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "wasabi - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\wasabi\api\apiinit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\precomp.cpp
+# ADD CPP /Yc"precomp.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\wasabicfg.h
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\Readme.txt
+# End Source File
+# End Target
+# End Project
diff --git a/Src/Plugins/General/gen_ff/wasabi.vcproj b/Src/Plugins/General/gen_ff/wasabi.vcproj
new file mode 100644
index 00000000..dcee2cf7
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wasabi.vcproj
@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="wasabi"
+ ProjectGUID="{CE8C15F0-959F-43F8-A195-F24B79144D40}"
+ SccProjectName=""
+ SccLocalPath="">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ UseOfATL="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2"
+ WholeProgramOptimization="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="0"
+ EnableIntrinsicFunctions="FALSE"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="TRUE"
+ AdditionalIncludeDirectories="../gen_ff;../Wasabi;../Wasabi/api/font/freetype/freetype2/include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;WINVER=0x400;NOSVCMGR;NOCBMGR"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="precomp.h"
+ PrecompiledHeaderFile=".\_build/Release/wasabi.pch"
+ AssemblerListingLocation=".\_build/Release/"
+ ObjectFile=".\_build/Release/"
+ ProgramDataBaseFileName=".\_build/Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/wasabi.lib"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\_build/Debug"
+ IntermediateDirectory=".\_build/Debug"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../gen_ff,../Wasabi,../Wasabi/api/font/freetype/freetype2/include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;NOSVCMGR;NOCBMGR"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ BufferSecurityCheck="TRUE"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="precomp.h"
+ PrecompiledHeaderFile=".\_build/Debug/wasabi.pch"
+ AssemblerListingLocation=".\_build/Debug/"
+ ObjectFile=".\_build/Debug/"
+ ProgramDataBaseFileName=".\_build/Debug/"
+ WarningLevel="4"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4100"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\_build/Debug\wasabi.lib"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Profiling|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ UseOfATL="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2"
+ WholeProgramOptimization="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="0"
+ EnableIntrinsicFunctions="FALSE"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="TRUE"
+ AdditionalIncludeDirectories="../gen_ff;../Wasabi;../Wasabi/api/font/freetype/freetype2/include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;WINVER=0x400;NOSVCMGR;NOCBMGR"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="FALSE"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="precomp.h"
+ PrecompiledHeaderFile=".\_build/Release/wasabi.pch"
+ AssemblerListingLocation=""
+ ObjectFile="$(IntDir)/"
+ ProgramDataBaseFileName=".\_build/Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\_build/Release\wasabi.lib"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+ <File
+ RelativePath="precomp.cpp">
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Profiling|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\Wasabi\bfc\platform\types.h">
+ </File>
+ <File
+ RelativePath="wasabicfg.h">
+ </File>
+ <Filter
+ Name="debug"
+ Filter="">
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl">
+ <File
+ RelativePath="..\Wasabi\api\config\cfgscriptobj.h">
+ </File>
+ <File
+ RelativePath="..\Wasabi\api\syscb\callbacks\corecbi.h">
+ </File>
+ <File
+ RelativePath="..\Wasabi\api\script\objects\c_script\h_rootobj.h">
+ </File>
+ <File
+ RelativePath="..\Wasabi\bfc\loadlib.h">
+ </File>
+ <File
+ RelativePath="..\Wasabi\api\skin\widgets\mb\mbsvc.h">
+ </File>
+ <File
+ RelativePath="..\Wasabi\api\wnd\paintset.h">
+ </File>
+ <File
+ RelativePath="..\Wasabi\api\syscb\callbacks\skincb.h">
+ </File>
+ <File
+ RelativePath="StdAfx.h">
+ </File>
+ <File
+ RelativePath="..\Wasabi\api\script\objects\core\svc_scriptcore.h">
+ </File>
+ <File
+ RelativePath="..\Wasabi\bfc\file\tmpnamestr.h">
+ </File>
+ <File
+ RelativePath="..\Wasabi\bfc\file\wildcharsenum.h">
+ </File>
+ </Filter>
+ <File
+ RelativePath="Readme.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Src/Plugins/General/gen_ff/wasabicfg.h b/Src/Plugins/General/gen_ff/wasabicfg.h
new file mode 100644
index 00000000..1140295f
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wasabicfg.h
@@ -0,0 +1,491 @@
+#ifndef __WASABI_CFG_H
+#define __WASABI_CFG_H
+
+#define GEN_FF
+#define WA5
+
+//#define _WASABIRUNTIME
+
+// Uncomment this to have an old-style global api pointer
+//#define WA3COMPATIBILITY
+
+
+#ifndef _WASABIRUNTIME
+
+#ifndef WA3COMPATIBILITY
+#define WASABINOMAINAPI
+#endif
+
+/*
+
+Comment or uncomment the following directives according to the needs of your application :
+
+*/
+
+/* note to the team:
+
+ the WANT_WASABI_API_* directives will go away once we're done splitting the api, their only purpose
+ is to split the api one bit at a time while the rest remains working. when it's done, all that will remain
+ will be the WASABI_COMPILE_* directives
+
+*/
+
+
+// This allows component (external plugins)
+//#define WASABI_COMPILE_COMPONENTS
+
+// This enables the layered UI
+#define WASABI_COMPILE_WND
+
+// This enables multiplexed timers
+#define WASABI_COMPILE_TIMERS
+
+// This enables xml group loading within the window api
+#define WASABI_COMPILE_SKIN
+#define WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE
+
+// This enables internationalizaiton
+// #define WASABI_COMPILE_UTF
+
+// This enables action handling in UI objects (clicks and keypresses)
+//#define WASABI_COMPILE_ACTIONS // CUT!!!
+
+// This enables UI scripting
+#define WASABI_COMPILE_SCRIPT
+
+// This enables keyboard locales in UI
+#define WASABI_COMPILE_LOCALES
+
+// This enables bitmap and truetype font rendering
+#define WASABI_COMPILE_FONTS
+
+//#define WASABI_FONT_RENDERER_USE_WIN32
+#define WASABI_FONT_RENDERER_USE_FREETYPE
+
+// This sets the static font renderer. If you are compiling with api_config, the attribute to set is { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } }, "Font Renderer"
+#if defined(WASABI_FONT_RENDERER_USE_WIN32)
+#define WASABI_FONT_RENDERER L"" // "" is Win32
+#elif defined(WASABI_FONT_RENDERER_USE_FREETYPE)
+#define WASABI_FONT_RENDERER L"Freetype" // Freetype lib
+#else
+#define WASABI_FONT_RENDERER L"" // "" default for OS
+#endif
+
+// This lets you override all bitmapfonts using TTF fonts (for internationalization). define to a function call or a global value to change this value dynamically.
+// If you are compiling with api_config, the attribute to set is { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } }, "Use bitmap fonts (no international support)"
+#define WASABI_FONT_TTFOVERRIDE 0 // 1 does all rendering with TTF
+
+#define WASABI_WNDMGR_ANIMATEDRECTS 0 // if api_config is compiled, the item controlling this is {280876CF-48C0-40bc-8E86-73CE6BB462E5};"Animated rects"
+#define WASABI_WNDMGR_FINDOPENRECT 0 // if api_config is compiled, the item controlling this is {280876CF-48C0-40bc-8E86-73CE6BB462E5};"Find open rect"
+#define WASABI_WNDMGR_LINKLAYOUTSCALES 0 // if api_config is compiled, the item controlling this is {9149C445-3C30-4e04-8433-5A518ED0FDDE};"Link layouts scale"
+#define WASABI_WNDMGR_LINKLAYOUTSALPHA 0 // if api_config is compiled, the item controlling this is {9149C445-3C30-4e04-8433-5A518ED0FDDE};"Link layouts alpha"
+#define WASABI_WNDMGR_DESKTOPALPHA 1 // if api_config is compiled, the item controlling this is {9149C445-3C30-4e04-8433-5A518ED0FDDE};"Enable desktop alpha"
+// This enables loading for pngs, jpgs (you need to add the necessary image loader services)
+#define WASABI_COMPILE_IMGLDR
+#define WASABI_COMPILE_IMGLDR_PNGREAD
+#define WASABI_COMPILE_IMGLDR_JPGREAD
+
+// This enables metadb support
+//#define WASABI_COMPILE_METADB
+
+// This enables config file support
+#define WASABI_COMPILE_CONFIG
+
+// This enables the filereader pipeline
+#define WASABI_COMPILE_FILEREADER
+
+// This enables the zip filereader
+//#define WASABI_COMPILE_ZIPREADER
+
+// This enables the xml parser for config and group loading
+#define WASABI_COMPILE_XMLPARSER
+
+// This enables system callback management
+#define WASABI_COMPILE_SYSCB
+
+// This enables centralized memory allocation/deallocation
+#define WASABI_COMPILE_MEMMGR
+
+#define WASABI_DIRS_FROMEXEPATH // otherwise, if the lib is running from a dll in another path, undefining that means the path are relative to the DLL path
+#define WASABI_SKINS_SUBDIRECTORY L"skins"
+#define WASABI_RESOURCES_SUBDIRECTORY L"plugins\\freeform"
+
+#define WASABI_COMPILE_MEDIACORE
+
+#define WASABI_COMPILE_WNDMGR
+#define WASABI_COMPILE_PAINTSETS
+#define WASABI_COMPILE_MAKIDEBUG
+
+#define WASABI_CUSTOMIMPL_MEDIACORE
+#define WASABI_WIDGETS_MEDIASLIDERS
+
+#define WASABI_CUSTOM_CONTEXTMENUS
+
+#define WASABI_CUSTOM_QUIT
+#define WASABI_CUSTOM_QUITFN { extern void appQuit(); appQuit(); }
+
+#define WASABI_CUSTOM_ONTOP
+
+#else // not _WASABIRUNTIME
+
+// this section should define the entire set of wasabi parts since this is a full runtime build
+
+#define WASABI_COMPILE_COMPONENTS
+#define WASABI_COMPILE_SKIN
+#define WASABI_COMPILE_ACTIONS
+#define WASABI_COMPILE_SCRIPT
+#define WASABI_COMPILE_FONTS
+#define WASABI_COMPILE_LOCALES
+#define WASABI_COMPILE_IMGLDR
+#define WASABI_COMPILE_IMGLDR_PNGREAD
+#define WASABI_COMPILE_IMGLDR_JPGREAD
+#define WASABI_COMPILE_METADB
+#define WASABI_COMPILE_CONFIG
+#define WASABI_COMPILE_FILEREADER
+#define WASABI_COMPILE_XMLPARSER
+#define WASABI_COMPILE_SYSCB
+#define WASABI_COMPILE_MEMMGR
+#define WASABI_COMPILE_SKIN_WA2
+#define WASABI_COMPILE_PAINTSETS
+#define WASABI_COMPILE_WNDMGR
+#define WASABI_COMPILE_MEDIACORE
+#define WASABI_COMPILE_TIMERS
+#define WASABI_COMPILE_WND
+#define WASABI_COMPILE_UTF
+#define WASABI_SKINS_SUBDIRECTORY "skins"
+#define WASABI_FONT_RENDERER "" // "" is Win32
+#define WASABI_WNDMGR_ANIMATEDRECTS 0 // if api_config is compiled, the item controlling this is {280876CF-48C0-40bc-8E86-73CE6BB462E5};"Animated rects"
+#define WASABI_WNDMGR_FINDOPENRECT 0 // if api_config is compiled, the item controlling this is {280876CF-48C0-40bc-8E86-73CE6BB462E5};"Find open rect"
+#define WASABI_COMPILE_MAKIDEBUG
+
+#endif // not _WASABIRUNTIME
+
+#ifdef _WASABIRUNTIME
+ #define WASABI_API_SYSTEM api
+ #define WASABI_API_APP api
+ #define WASABI_API_COMPONENT api
+ #define WASABI_API_SVC api
+ #define WASABI_API_SYSCB api
+ #define WASABI_API_MAKI api
+ #define WASABI_API_UTF api
+ #define WASABI_API_WND api
+ #define WASABI_API_IMGLDR api
+ #define WASABI_API_FILE api
+ #define WASABI_API_TIMER api
+ #define WASABI_API_WNDMGR api
+ #define WASABI_API_SKIN api
+ #define WASABI_API_METADB api
+ #define WASABI_API_LOCALE api
+ #define WASABI_API_CONFIG api
+ #define WASABI_API_FONT api
+ #define WASABI_API_MEMMGR api
+ #define WASABI_API_XML api
+ #define WASABI_API_MEDIACORE api
+ #define WASABI_API_MAKIDEBUG debugApi
+
+#else // _WASABIRUNTIME
+
+ #define WASABI_API_SYSTEM systemApi
+
+ #define WASABI_API_APP applicationApi
+ #define WASABI_API_SVC serviceApi
+ #define WASABI_API_SYSCB sysCallbackApi
+
+ #ifdef WASABI_COMPILE_COMPONENTS
+ #define WASABI_API_COMPONENT componentApi
+ #endif
+
+ #ifdef WASABI_COMPILE_SCRIPT
+ #define WASABI_API_MAKI makiApi
+ #endif
+
+ #ifdef WASABI_COMPILE_UTF
+ #define WASABI_API_UTF utfApi
+ #endif
+
+ #ifdef WASABI_COMPILE_WND
+ #define WASABI_API_WND wndApi
+ #endif
+
+ #ifdef WASABI_COMPILE_IMGLDR
+ #define WASABI_API_IMGLDR imgLoaderApi
+ #endif
+
+ #ifdef WASABI_COMPILE_FILEREADER
+ #define WASABI_API_FILE fileApi
+ #endif
+
+ #ifdef WASABI_COMPILE_TIMERS
+ #define WASABI_API_TIMER timerApi
+ #endif
+
+ #ifdef WASABI_COMPILE_WNDMGR
+ #define WASABI_API_WNDMGR wndManagerApi
+ #endif
+
+ #ifdef WASABI_COMPILE_SKIN
+ #define WASABI_API_SKIN skinApi
+ #endif
+
+ #ifdef WASABI_COMPILE_METADB
+ #define WASABI_API_METADB metadbApi
+ #endif
+
+ #ifdef WASABI_COMPILE_LOCALES
+ #define WASABI_API_LOCALE localesApi
+ #endif
+
+ #ifdef WASABI_COMPILE_CONFIG
+ #define WASABI_API_CONFIG configApi
+ #endif
+
+ #ifdef WASABI_COMPILE_FONTS
+ #define WASABI_API_FONT fontApi
+ #endif
+
+ #ifdef WASABI_COMPILE_MEMMGR
+ #define WASABI_API_MEMMGR memmgrApi
+ #endif
+
+ #ifdef WASABI_COMPILE_XMLPARSER
+ #define WASABI_API_XML xmlApi
+ #endif
+
+ #ifdef WASABI_COMPILE_MEDIACORE
+ #define WASABI_API_MEDIACORE coreApi
+ #endif
+
+
+ #ifdef WASABI_COMPILE_MAKIDEBUG
+ #define WASABI_API_MAKIDEBUG debugApi
+ #endif
+
+#endif // _WASABIRUNTIME
+
+// #define WASABI_EXTERNAL_GUIOBJECTS
+
+#define WASABI_WIDGETS_GUIOBJECT
+#define WASABI_WIDGETS_LAYER
+#define WASABI_WIDGETS_TEXT
+#define WASABI_WIDGETS_BUTTON
+#define WASABI_WIDGETS_TGBUTTON
+#define WASABI_WIDGETS_ANIMLAYER
+#define WASABI_WIDGETS_GROUPLIST
+#define WASABI_WIDGETS_MOUSEREDIR
+#define WASABI_WIDGETS_SLIDER
+#define WASABI_WIDGETS_MEDIAVIS
+#define WASABI_WIDGETS_MEDIAEQCURVE
+#define WASABI_WIDGETS_MEDIASTATUS
+//#define WASABI_WIDGETS_SVCWND
+#define WASABI_WIDGETS_EDIT
+#define WASABI_WIDGETS_TITLEBAR
+#define WASABI_WIDGETS_COMPBUCK
+#define WASABI_WIDGETS_BROWSER
+#define WASABI_WIDGETS_FRAME
+#define WASABI_WIDGETS_GRID
+//#define WASABI_WIDGETS_QUERYDRAG
+//#define WASABI_WIDGETS_QUERYLIST
+//#define WASABI_WIDGETS_FILTERLIST
+//#define WASABI_WIDGETS_QUERYLINE
+#define WASABI_WIDGETS_TABSHEET
+#define WASABI_WIDGETS_CHECKBOX
+#define WASABI_WIDGETS_TITLEBOX
+#define WASABI_WIDGETS_CUSTOMOBJECT
+#define WASABI_WIDGETS_OSWNDHOST
+#define WASABI_WIDGETS_RADIOGROUP
+#define WASABI_WIDGETS_LIST
+#define WASABI_WIDGETS_TREE
+#define WASABI_WIDGETS_DROPDOWNLIST
+#define WASABI_WIDGETS_COMBOBOX
+#define WASABI_WIDGETS_HISTORYEDITBOX
+#define WASABI_WIDGETS_OBJECTDIRECTORY
+#define WASABI_WIDGETS_RECTANGLE
+#define WASABI_WIDGETS_PATHPICKER
+#define WASABI_WIDGETS_GRADIENT
+#define WASABI_WIDGETS_MENUBUTTON
+#define WASABI_WIDGETS_MENU
+#define WASABI_WIDGETS_WNDHOLDER
+#define WASABI_WIDGETS_LAYOUTSTATUS
+#define WASABI_WIDGETS_TOOLTIPS
+
+#include "../Winamp/buildType.h"
+#if defined(_DEBUG) || defined(WASABI_DEBUG)// || defined(INTERNAL) || defined(BETA) || defined(NIGHT)
+#define WASABI_COMPILE_STATSWND
+#endif
+
+#if defined(_DEBUG)
+#ifndef WASABI_DEBUG
+#define WASABI_DEBUG
+#endif
+#endif
+
+#define WASABI_TOOLOBJECT_HIDEOBJECT
+#define WASABI_TOOLOBJECT_SENDPARAMS
+#define WASABI_TOOLOBJECT_ADDPARAMS
+
+// #endif // WASABI_EXTERNAL_GUIOBJECTS
+#define WASABI_COMPILE_COLORTHEMES
+
+#define WASABI_SCRIPTOBJECTS_POPUP
+#define WASABI_SCRIPTOBJECTS_LIST
+#define WASABI_SCRIPTOBJECTS_BITLIST
+#define WASABI_SCRIPTOBJECTS_REGION
+#define WASABI_SCRIPTOBJECTS_TIMER
+#define WASABI_SCRIPTOBJECTS_MAP
+#define WASABI_SCRIPTOBJECTS_EMBEDDEDXUI // needed by 3rd+ level objects
+
+#ifndef WASABI_EXTERNAL_GUIOBJECTS
+#define WASABI_SCRIPTOBJECTS_WAC
+#endif // WASABI_EXTERNAL_GUIOBJECTS
+
+// lone is super dirty but wants to get stuff working. we need to clean that up
+#ifdef WASABI_CUSTOMIMPL_MEDIACORE
+class api_core;
+extern api_core *createCustomCoreApi();
+extern void destroyCustomCoreApi(api_core *core);
+#endif
+
+#define WASABI_WNDMGR_ALLCONTAINERSDYNAMIC 0
+#define WASABI_WNDMGR_NORESPAWN
+#define WASABI_WNDMGR_OSMSGBOX
+
+#define WASABI_STATICVARMGR
+#define WASABI_CUSTOM_MODULE_SVCMGR
+
+#define ON_LAYOUT_CHANGED { extern void onLayoutChanged(); onLayoutChanged(); }
+
+#define ON_FATAL_SKIN_ERROR { extern void onFatalSkinError(); onFatalSkinError(); }
+
+#define ON_CREATE_EXTERNAL_WINDOW_GUID(x, y) { extern int onCreateExternalWindowGuid(GUID g); y = onCreateExternalWindowGuid(x); }
+
+#define ON_TOGGLE_DESKTOPALPHA(v) { extern void onToggleDesktopAlpha(int v); onToggleDesktopAlpha(v); }
+#define ON_TWEAK_CONTAINER_NAMEW(x) { extern const wchar_t *onTweakContainerNameW(const wchar_t *name); x = onTweakContainerNameW(x); }
+#define ON_TWEAK_RENDER_RATIO(x) { extern double onTweakRenderRatio(double v); x = onTweakRenderRatio(x); }
+#define ON_CUSTOM_ALTF4 { extern void onCustomAltF4(); onCustomAltF4(); }
+
+#define WASABI_DEFAULT_STDCONTAINER L"resizable_status"
+
+#define SWITCH_SKIN(x) { extern void switchSkin(const wchar_t *name); switchSkin(x); }
+#define IS_SKIN_STILL_LOADING(x) { extern int isSkinStillLoading(); x = isSkinStillLoading(); }
+
+#define ON_LOAD_EXTRA_COLORTHEMES() { extern void loadExtraColorThemes(); loadExtraColorThemes(); }
+
+#define LOCALES_CUSTOM_LOAD(x) { extern const wchar_t *localesCustomGetFile(); x = localesCustomGetFile(); }
+
+#define DEFAULT_CROSSFADE_ENABLED FALSE
+
+#define CUSTOM_VARS(x, y) { extern const wchar_t *getCustomVar(const wchar_t *var); y = getCustomVar(x); }
+
+#define WASABI_NO_RELEASEMODE_DEBUGSTRINGS
+
+#define WASABI_CUSTOM_MINIDB(field, buf, len) { extern void getCustomMetaData(const wchar_t *f, wchar_t *b, int l); getCustomMetaData(field, buf, len); }
+
+#define GET_SONG_INFO_TEXT(ret) { extern const wchar_t *getSongInfoText(); ret = getSongInfoText(); }
+
+#define GET_SONG_INFO_TEXT_TRANSLATED(ret) { extern const wchar_t *getSongInfoTextTranslated(); ret = getSongInfoTextTranslated(); }
+
+#define GET_KBDFORWARD_WND(g, wnd) { extern OSWINDOWHANDLE getKeyboardForwardWnd(GUID g); wnd = getKeyboardForwardWnd(g); }
+
+#define WASABI_EDITWND_LISTCOLORS // editwnds use list foreground & background rather than their own colors
+
+#define WASABI_APPBAR_ONDOCKCHANGED(wnd) { extern void onAppBarDockChanged(ifc_window *w); onAppBarDockChanged(wnd); }
+
+#define WASABI_GET_VERSION(cs, n) { extern const char *getVersion(); STRNCPY(cs, getVersion(), n); cs[n] = 0; }
+
+#define WASABI_ON_MAIN_MOVE(hwnd) { extern void onMainLayoutMove(HWND w); onMainLayoutMove(hwnd); }
+
+#define WASABI_ON_REPARENT(hwnd) { extern void onReParent(HWND w); onReParent(hwnd); }
+
+#define WASABI_ON_REINIT(hwnd) { extern void onReInit(HWND w); onReInit(hwnd); }
+
+#define WASABI_GET_TEMPDISABLE_AOT(x) { extern int getAOTTempDisable(); x = getAOTTempDisable(); }
+
+#define WASABI_CHECK_CAN_EXIT(x) { extern int canExitWinamp(); x = canExitWinamp(); }
+
+#define WASABI_CHECK_OFFSCREENCHECK_DISABLE(x) { extern int fsMonitorIsFS(); x = fsMonitorIsFS(); }
+
+#define WASABI_MODAL_PUSH { extern void modalPush(); modalPush(); }
+#define WASABI_MODAL_POP { extern void modalPop(); modalPop(); }
+
+// config defaults
+
+#define DEFAULT_DESKTOPALPHA TRUE
+#define DEFAULT_LINKLAYOUTSCALE TRUE
+#define DEFAULT_LINKLAYOUTSALPHA FALSE
+#define DEFAULT_LINKALLALPHA TRUE
+#define DEFAULT_LINKALLRATIO FALSE
+#define DEFAULT_LINKEDALPHA 255
+#define DEFAULT_AUTOOPACITYTIME 2000
+#define DEFAULT_AUTOOPACITYFADEIN 250
+#define DEFAULT_AUTOOPACITYFADEOUT 1000
+#define DEFAULT_AUTOOPACITYTYPE 0
+#define DEFAULT_EXTENDAUTOOPACITY 25
+#define DEFAULT_USERATIOLOCKS FALSE
+#define DEFAULT_TIMERRESOLUTION 33
+#define DEFAULT_TOOLTIPS TRUE
+#define DEFAULT_TEXTSPEED 1.0f/3.0f
+#define DEFAULT_TEXTINCREMENT 1
+#define DEFAULT_APPBARHIDETIME 500
+#define DEFAULT_APPBARSHOWTIME 500
+
+#define UTF8 0
+#define WANT_UTF8_WARNINGS
+
+//#define DROP_BITMAP_ON_IDLE
+
+//#include "../../bfc/api/api_system.h"
+#include <api/application/api_application.h>
+#include <api/service/api_service.h>
+#include <api/syscb/api_syscbi.h>
+
+#ifdef WASABI_COMPILE_MEMMGR
+# include <api/memmgr/api_memmgr.h>
+#endif
+
+#ifdef WASABI_COMPILE_SCRIPT
+# include <api/script/api_maki.h>
+#endif
+
+#ifdef WASABI_COMPILE_FONTS
+# include <api/font/api_font.h>
+#endif
+
+#ifdef WASABI_COMPILE_WND
+# include <api/wnd/api_wnd.h>
+#endif
+
+#ifdef WASABI_COMPILE_IMGLDR
+# include <api/imgldr/api_imgldr.h>
+#endif
+
+#ifdef WASABI_COMPILE_FILEREADER
+# include <api/filereader/api_filereader.h>
+#endif
+
+#ifdef WASABI_COMPILE_TIMERS
+# include <api/timer/api_timer.h>
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+# include <api/wndmgr/api_wndmgr.h>
+#endif
+
+#ifdef WASABI_COMPILE_LOCALES
+# include <api/locales/api_locales.h>
+#endif
+
+#ifdef WASABI_COMPILE_CONFIG
+# include <api/config/api_config.h>
+#endif
+
+# include "../xml/obj_xml.h"
+
+#ifdef WASABI_COMPILE_SKIN
+# include <api/skin/api_skin.h>
+#endif
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+# include <api/script/debugger/api_makidebug.h>
+#endif
+
+#endif