MusicMod: Moved it from Branches to Externals, I guess there usually is no Branches dir in the trunk dir, so this may look a little better

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2174 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson committed 2009-02-09 15:29:35 +00:00
1 parent 013e9bed93
commit 3e53828406
116 files changed
+14 -12

No files matched your search

Binary file not shown.
Binary file not shown.
+925
View File
@@ -0,0 +1,925 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="Player"
ProjectGUID="{0B72B5D6-5D72-4391-84A7-9CCA5392668A}"
RootNamespace="Plainamp"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\..\..\Binary\win32\"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\Source\Core\Common\Src"
PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_SECURE_SCL=0"
MinimalRebuild="false"
BasicRuntimeChecks="0"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libzlib1.lib comctl32.lib LIBCMTD.LIB winmm.lib"
OutputFile="$(OutDir)/Plainamp.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="Lib"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
SubSystem="0"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary="$(TargetDir)$(TargetName).lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="..\..\..\Binary\x64\"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="false"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libzlib1.lib comctl32.lib winmm.lib"
OutputFile="$(OutDir)/Plainamp.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\Lib"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
SubSystem="0"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary="$(TargetDir)$(TargetName).lib"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\..\..\Binary\win32\"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="..\..\..\Source\Core\Common\Src"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_SECURE_SCL=0"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/NODEFAULTLIB:msvcrt"
AdditionalDependencies="libzlib1.lib comctl32.lib winmm.lib"
OutputFile="$(OutDir)/Plainamp.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="Lib"
GenerateDebugInformation="false"
SubSystem="0"
OptimizeReferences="2"
EnableCOMDATFolding="2"
EntryPointSymbol=""
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="..\..\..\Binary\x64\"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libzlib1.lib comctl32.lib winmm.lib"
OutputFile="$(OutDir)/Plainamp.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="Lib"
GenerateDebugInformation="false"
SubSystem="0"
OptimizeReferences="2"
EnableCOMDATFolding="2"
EntryPointSymbol=""
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="DebugFast|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="..\..\..\Source\Core\Common\Src"
PreprocessorDefinitions="WIN32;DEBUGFAST;_WINDOWS;_SECURE_SCL=0"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/NODEFAULTLIB:msvcrt"
AdditionalDependencies="libzlib1.lib comctl32.lib winmm.lib"
OutputFile="$(OutDir)/Plainamp.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="Lib"
GenerateDebugInformation="false"
SubSystem="0"
OptimizeReferences="2"
EnableCOMDATFolding="2"
EntryPointSymbol=""
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="DebugFast|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libzlib1.lib comctl32.lib winmm.lib"
OutputFile="$(OutDir)/Plainamp.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="Lib"
GenerateDebugInformation="false"
SubSystem="0"
OptimizeReferences="2"
EnableCOMDATFolding="2"
EntryPointSymbol=""
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Externals"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<Filter
Name="fftw3"
>
<File
RelativePath=".\Src\fftw3\fftw3.h"
>
</File>
</Filter>
<Filter
Name="Winamp"
>
<File
RelativePath=".\Src\Winamp\Dsp.h"
>
</File>
<File
RelativePath=".\Src\Winamp\Gen.h"
>
</File>
<File
RelativePath=".\Src\Winamp\In2.h"
>
</File>
<File
RelativePath=".\Src\Winamp\Out.h"
>
</File>
<File
RelativePath=".\Src\Winamp\Vis.h"
>
</File>
<File
RelativePath=".\Src\Winamp\wa_ipc.h"
>
</File>
<File
RelativePath=".\Src\Winamp\wa_msgids.h"
>
</File>
</Filter>
<Filter
Name="zlib"
>
<File
RelativePath=".\Src\zlib\zconf.h"
>
</File>
<File
RelativePath=".\Src\zlib\zlib.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\Src\Resources\Buttons.bmp"
>
</File>
<File
RelativePath=".\Src\Resources\Plainamp.ico"
>
</File>
<File
RelativePath=".\Src\Resources\resrc1.h"
>
</File>
<File
RelativePath=".\Src\Resources\resrc1.rc"
>
</File>
</Filter>
<Filter
Name="Playlist"
>
<File
RelativePath=".\Src\Playlist.cpp"
>
</File>
<File
RelativePath=".\Src\Playlist.h"
>
</File>
<File
RelativePath=".\Src\PlaylistControler.cpp"
>
</File>
<File
RelativePath=".\Src\PlaylistControler.h"
>
</File>
<File
RelativePath=".\Src\PlaylistModel.h"
>
</File>
<File
RelativePath=".\Src\PlaylistView.cpp"
>
</File>
<File
RelativePath=".\Src\PlaylistView.h"
>
</File>
</Filter>
<Filter
Name="Plugins"
>
<File
RelativePath=".\Src\DspPlugin.cpp"
>
</File>
<File
RelativePath=".\Src\DspPlugin.h"
>
</File>
<File
RelativePath=".\Src\GenPlugin.cpp"
>
</File>
<File
RelativePath=".\Src\GenPlugin.h"
>
</File>
<File
RelativePath=".\Src\InputPlugin.cpp"
>
</File>
<File
RelativePath=".\Src\InputPlugin.h"
>
</File>
<File
RelativePath=".\Src\OutputPlugin.cpp"
>
</File>
<File
RelativePath=".\Src\OutputPlugin.h"
>
</File>
<File
RelativePath=".\Src\Plugin.cpp"
>
</File>
<File
RelativePath=".\Src\Plugin.h"
>
</File>
<File
RelativePath=".\Src\PluginManager.cpp"
>
</File>
<File
RelativePath=".\Src\PluginManager.h"
>
</File>
</Filter>
<Filter
Name="MusicMod"
>
<File
RelativePath=".\Src\Global.h"
>
</File>
<File
RelativePath=".\Src\Main.cpp"
>
</File>
<File
RelativePath=".\Src\Main.h"
>
</File>
<File
RelativePath=".\Src\Playback.cpp"
>
</File>
<File
RelativePath=".\Src\Playback.h"
>
</File>
<File
RelativePath=".\Src\Player.cpp"
>
</File>
<File
RelativePath=".\Src\PlayerExport.cpp"
>
</File>
<File
RelativePath=".\Src\PlayerExport.h"
>
</File>
<File
RelativePath=".\Src\Timer.cpp"
>
</File>
</Filter>
<Filter
Name="EmaBox"
>
<File
RelativePath=".\Src\Emabox\Emabox.cpp"
>
</File>
<File
RelativePath=".\Src\Emabox\Emabox.h"
>
</File>
<File
RelativePath=".\Src\Emabox\EmaboxConfig.h"
>
</File>
</Filter>
<Filter
Name="Other"
>
<File
RelativePath=".\Src\AddDirectory.cpp"
>
</File>
<File
RelativePath=".\Src\AddDirectory.h"
>
</File>
<File
RelativePath=".\Src\AddFiles.cpp"
>
</File>
<File
RelativePath=".\Src\AddFiles.h"
>
</File>
<File
RelativePath=".\Src\afxres.h"
>
</File>
<File
RelativePath=".\Src\Console.cpp"
>
</File>
<File
RelativePath=".\Src\Console.h"
>
</File>
<File
RelativePath=".\Src\DspModule.cpp"
>
</File>
<File
RelativePath=".\Src\DspModule.h"
>
</File>
<File
RelativePath=".\Src\Embed.cpp"
>
</File>
<File
RelativePath=".\Src\Embed.h"
>
</File>
<File
RelativePath=".\Src\Font.cpp"
>
</File>
<File
RelativePath=".\Src\Font.h"
>
</File>
<File
RelativePath=".\Src\GlobalVersion.h"
>
</File>
<File
RelativePath=".\Src\Input.cpp"
>
</File>
<File
RelativePath=".\Src\Input.h"
>
</File>
<File
RelativePath=".\Src\Lock.cpp"
>
</File>
<File
RelativePath=".\Src\Lock.h"
>
</File>
<File
RelativePath=".\Src\Output.cpp"
>
</File>
<File
RelativePath=".\Src\Output.h"
>
</File>
<File
RelativePath=".\Src\Path.cpp"
>
</File>
<File
RelativePath=".\Src\Path.h"
>
</File>
<File
RelativePath=".\Src\PlaybackEq.cpp"
>
</File>
<File
RelativePath=".\Src\PlaybackOrder.cpp"
>
</File>
<File
RelativePath=".\Src\Prefs.cpp"
>
</File>
<File
RelativePath=".\Src\Prefs.h"
>
</File>
<File
RelativePath=".\Src\Rebar.cpp"
>
</File>
<File
RelativePath=".\Src\Rebar.h"
>
</File>
<File
RelativePath=".\Src\Status.cpp"
>
</File>
<File
RelativePath=".\Src\Status.h"
>
</File>
<File
RelativePath=".\Src\Unicode.cpp"
>
</File>
<File
RelativePath=".\Src\Unicode.h"
>
</File>
<File
RelativePath=".\Src\Util.cpp"
>
</File>
<File
RelativePath=".\Src\Util.h"
>
</File>
<File
RelativePath=".\Src\VisCache.cpp"
>
</File>
<File
RelativePath=".\Src\VisCache.h"
>
</File>
<File
RelativePath=".\Src\VisModule.cpp"
>
</File>
<File
RelativePath=".\Src\VisModule.h"
>
</File>
<File
RelativePath=".\Src\VisPlugin.cpp"
>
</File>
<File
RelativePath=".\Src\VisPlugin.h"
>
</File>
<File
RelativePath=".\Src\Winamp.cpp"
>
</File>
<File
RelativePath=".\Src\Winamp.h"
>
</File>
</Filter>
<Filter
Name="Config"
>
<File
RelativePath=".\Src\Config.cpp"
>
</File>
<File
RelativePath=".\Src\Config.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+364
View File
@@ -0,0 +1,364 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "AddDirectory.h"
#include "Playlist.h"
#include "Main.h"
#include "InputPlugin.h"
#include <stdio.h>
#include <shlobj.h>
#include <vector>
#include <algorithm>
using namespace std;
HWND WindowBrowse = NULL;
void SearchFolder( TCHAR * szPath );
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
LPITEMIDLIST GetCurrentFolder()
{
/*
How To Convert a File Path to an ITEMIDLIST
http://support.microsoft.com/default.aspx?scid=kb;en-us;132750
*/
LPITEMIDLIST pidl;
LPSHELLFOLDER pDesktopFolder;
TCHAR szPath[ MAX_PATH ];
#ifndef PA_UNICODE
OLECHAR olePath[ MAX_PATH ];
#endif
ULONG chEaten;
ULONG dwAttributes;
HRESULT hr;
//
// Get the path we need to convert.
//
GetCurrentDirectory( MAX_PATH, szPath );
//
// Get a pointer to the Desktop's IShellFolder interface.
//
if( SUCCEEDED( SHGetDesktopFolder( &pDesktopFolder ) ) )
{
//
// IShellFolder::ParseDisplayName requires the file name be in
// Unicode.
//
#ifndef PA_UNICODE
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, szPath, -1, olePath, MAX_PATH );
#endif
//
// Convert the path to an ITEMIDLIST.
//
// hr = pDesktopFolder->lpVtbl->ParseDisplayName(
hr = pDesktopFolder->ParseDisplayName(
( HWND__ * )pDesktopFolder,
NULL,
#ifndef PA_UNICODE
olePath,
#else
szPath,
#endif
&chEaten,
&pidl,
&dwAttributes
);
if( FAILED( hr ) )
{
// Handle error.
return NULL;
}
//
// pidl now contains a pointer to an ITEMIDLIST for .\readme.txt.
// This ITEMIDLIST needs to be freed using the IMalloc allocator
// returned from SHGetMalloc().
//
// release the desktop folder object
// pDesktopFolder->lpVtbl->Release();
pDesktopFolder->Release();
return pidl;
}
else
{
return NULL;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
BOOL CALLBACK EnumChildProc( HWND hwnd, LPARAM lp )
{
TCHAR szClassName[ 8 ] = TEXT( "\0" );
HWND * hFirstFoundStatic = ( ( HWND * )lp );
if( GetClassName( hwnd, szClassName, 7 ) )
{
if( !_tcscmp( szClassName, TEXT( "Static" ) ) )
{
if( *hFirstFoundStatic )
{
// Both found
RECT r1;
GetWindowRect( *hFirstFoundStatic, &r1 );
RECT r2;
GetWindowRect( hwnd, &r2 );
// First must be taller one
if( r1.bottom - r1.top < r2.bottom - r2.top )
{
// Swap
RECT r = r1;
HWND h = *hFirstFoundStatic;
r1 = r2;
*hFirstFoundStatic = hwnd;
r2 = r;
hwnd = h;
}
POINT xy2 = { r2.left, r2.top };
ScreenToClient( WindowBrowse, &xy2 );
SetWindowPos(
*hFirstFoundStatic,
NULL,
0,
0,
r2.right - r2.left,
r2.bottom - r2.top,
SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER
);
SetWindowPos(
hwnd,
NULL,
xy2.x,
xy2.y + ( r2.bottom - r2.top ) - ( r1.bottom - r1.top ),
r1.right - r1.left,
r1.bottom - r1.top,
SWP_NOOWNERZORDER | SWP_NOZORDER
);
return FALSE; // Stop
}
else
{
// First found
*hFirstFoundStatic = hwnd;
}
}
}
return TRUE; // Continue
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
int CALLBACK BrowseCallbackProc( HWND hwnd, UINT message, LPARAM lp, LPARAM wp )
{
switch( message )
{
case BFFM_INITIALIZED:
{
WindowBrowse = hwnd;
// Init with curdir
SendMessage( hwnd, BFFM_SETSELECTION, FALSE, ( LPARAM )GetCurrentFolder() );
// Swap static dimensions
HWND hFirstFoundStatic = NULL;
EnumChildWindows( hwnd, EnumChildProc, ( LPARAM )&hFirstFoundStatic );
break;
}
case BFFM_SELCHANGED:
{
TCHAR szPath[ MAX_PATH ] = TEXT( "\0" );
SHGetPathFromIDList( ( LPITEMIDLIST )lp, szPath );
SendMessage( hwnd, BFFM_SETSTATUSTEXT, 0, ( LPARAM )szPath );
break;
}
case BFFM_VALIDATEFAILED:
return TRUE;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/// Shows a Browse-For-Folder dialog and recursively adds supported files
/// to the playlist. Files are sorted by full filaname before being added.
////////////////////////////////////////////////////////////////////////////////
void AddDirectory()
{
TCHAR szPath[ MAX_PATH ];
BROWSEINFO bi = { 0 };
bi.hwndOwner = WindowMain;
bi.pidlRoot = NULL; // Desktop folder
bi.lpszTitle = TEXT( "Please select a directory:" );
bi.ulFlags = BIF_VALIDATE | BIF_STATUSTEXT;
bi.lpfn = BrowseCallbackProc;
LPITEMIDLIST pidl = SHBrowseForFolder( &bi );
if( !pidl ) return;
// Get path
SHGetPathFromIDList( pidl, szPath );
// Search
SearchFolder( szPath );
// Stay here
SetCurrentDirectory( szPath );
// Free memory used
IMalloc * imalloc = 0;
if( SUCCEEDED( SHGetMalloc( &imalloc ) ) )
{
imalloc->Free( pidl );
imalloc->Release();
}
}
////////////////////////////////////////////////////////////////////////////////
/* Warning: There is SetCurrentDirectory() here, be aware of it. We don't really
want to use that. */
////////////////////////////////////////////////////////////////////////////////
void SearchFolder( TCHAR * szPath )
{
// Remove trailing backslash
int iPathLen = ( int )_tcslen( szPath );
if( iPathLen < 1 ) return;
if( szPath[ iPathLen - 1 ] == TEXT( '\\' ) )
{
iPathLen--;
}
// Init working buffer
TCHAR szFullpath[ MAX_PATH ];
memcpy( szFullpath, szPath, iPathLen * sizeof( TCHAR ) );
szFullpath[ iPathLen ] = TEXT( '\\' );
szFullpath[ iPathLen + 1 ] = TEXT( '\0' );
// Make pattern
_tcscpy( szFullpath + iPathLen + 1, TEXT( "*" ) );
// Find
vector <TCHAR *> Files;
vector <TCHAR *> Dirs;
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
hFind = FindFirstFile( szFullpath, &FindFileData );
if( hFind == INVALID_HANDLE_VALUE ) return;
do
{
// Skip "." and ".."
if( !_tcscmp( FindFileData.cFileName, TEXT( "." ) ) ||
!_tcscmp( FindFileData.cFileName, TEXT( ".." ) ) ) continue;
// Make full path
_tcscpy( szFullpath + iPathLen + 1, FindFileData.cFileName );
// Is directory?
TCHAR * szPartname = new TCHAR[ MAX_PATH ];
_tcscpy( szPartname, FindFileData.cFileName );
if( SetCurrentDirectory( szFullpath ) )
{
// New dir
Dirs.push_back( szPartname );
continue;
}
// Search "."
const int iFilenameLen = ( int )_tcslen( FindFileData.cFileName );
TCHAR * szExt = FindFileData.cFileName + iFilenameLen - 1;
while( ( szExt > FindFileData.cFileName ) && ( *szExt != TEXT( '.' ) ) ) szExt--;
if( *szExt != TEXT( '.' ) ) continue;
szExt++;
// Check extension
map <TCHAR *, InputPlugin *, TextCompare>::iterator iter = ext_map.find( szExt );
if( iter == ext_map.end() ) continue;
// New file
Files.push_back( szPartname );
}
while( FindNextFile( hFind, &FindFileData ) );
FindClose( hFind );
vector <TCHAR *>::iterator iter;
// Sort and recurse directories
sort( Dirs.begin(), Dirs.end(), TextCompare() );
iter = Dirs.begin();
while( iter != Dirs.end() )
{
TCHAR * szWalk = *iter;
_tcscpy( szFullpath + iPathLen + 1, szWalk );
SearchFolder( szFullpath );
iter++;
}
// Sort and add files
sort( Files.begin(), Files.end(), TextCompare() );
iter = Files.begin();
while( iter != Files.end() )
{
TCHAR * szWalk = *iter;
TCHAR * szKeep = new TCHAR[ MAX_PATH ];
memcpy( szKeep, szFullpath, ( iPathLen + 1 ) * sizeof( TCHAR ) );
_tcscpy( szKeep + iPathLen + 1, szWalk );
playlist->PushBack( szKeep );
iter++;
}
}
+26
View File
@@ -0,0 +1,26 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_ADD_DIRECTORY_H
#define PA_ADD_DIRECTORY_H
#include "Global.h"
void AddDirectory();
#endif // PA_ADD_DIRECTORY_H
+181
View File
@@ -0,0 +1,181 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "AddFiles.h"
#include "InputPlugin.h"
#include "Main.h"
#include "Playlist.h"
#include <commdlg.h>
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
void AddFiles()
{
int total = 0;
int iFilterLen = 0;
InputPlugin * input;
vector <InputPlugin *>::iterator iter;
// Get len
// if( input_plugins.empty() ) return;
iter = input_plugins.begin();
while( iter != input_plugins.end() )
{
input = *iter;
if( !input ) iter++;
iFilterLen += input->iFiltersLen;
iter++;
}
// if( !iFilterLen ) return;
iFilterLen += 40 + 29 + ( int )ext_map.size() * ( 2 + 4 + 1 ) + 7;
TCHAR * szFilters = new TCHAR[ iFilterLen ];
TCHAR * walk = szFilters;
// ..................1.........1....\....\.1.........1........\.1...
memcpy( walk, TEXT( "All files (*.*)\0*.*\0All supported types\0" ), 40 * sizeof( TCHAR ) );
walk += 40;
// Add all extensions as ";*.ext"
// if( ext_map.empty() ) return;
map <TCHAR *, InputPlugin *, TextCompare>::iterator iter_ext = ext_map.begin();
bool bFirst = true;
while( iter_ext != ext_map.end() )
{
if( !bFirst )
{
memcpy( walk, TEXT( ";*." ), 3 * sizeof( TCHAR ) );
walk += 3;
}
else
{
memcpy( walk, TEXT( "*." ), 2 * sizeof( TCHAR ) );
walk += 2;
bFirst = false;
}
TCHAR * szExt = iter_ext->first;
int uLen = ( int )_tcslen( szExt );
memcpy( walk, szExt, uLen * sizeof( TCHAR ) );
walk += uLen;
iter_ext++;
}
// *walk = TEXT( '\0' );
// walk++;
// ..................1..........1...
memcpy( walk, TEXT( ";*.m3u\0" ), 7 * sizeof( TCHAR ) );
walk += 7;
// ..................1.........1.........1...........1...
memcpy( walk, TEXT( "Playlist files (*.M3U)\0*.m3u\0" ), 29 * sizeof( TCHAR ) );
walk += 29;
// Copy filters
iter = input_plugins.begin();
while( iter != input_plugins.end() )
{
input = *iter;
if( !input ) iter++;
memcpy( walk, input->szFilters, input->iFiltersLen * sizeof( TCHAR ) );
walk += input->iFiltersLen;
iter++;
}
*walk = TEXT( '\0' );
walk++;
////////////////////////////////////////////////////////////////////////////////
static TCHAR szFilenames[ 20001 ];
*szFilenames = TEXT( '\0' ); // Each time!
OPENFILENAME ofn;
memset( &ofn, 0, sizeof( OPENFILENAME ) );
ofn.lStructSize = sizeof( OPENFILENAME );
ofn.hwndOwner = WindowMain;
ofn.hInstance = g_hInstance;
ofn.lpstrFilter = szFilters; // "MPEG Layer 3\0*.mp3\0";
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 2;
ofn.lpstrFile = szFilenames;
ofn.nMaxFile = 20000;
ofn.Flags = OFN_EXPLORER | OFN_ALLOWMULTISELECT | OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.nMaxFileTitle = 0, // NULL;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = TEXT( "Add files" );
if( !GetOpenFileName( &ofn ) ) return;
int uDirLen = ( int )_tcslen( szFilenames );
TCHAR * szDir = szFilenames;
TCHAR * szFileWalk = szDir + uDirLen + 1;
if( *szFileWalk == TEXT( '\0' ) ) // "\0\0" or just "\0"?
{
// \0\0 -> Single file
if( !_tcsncmp( szDir + uDirLen - 3, TEXT( "m3u" ), 3 ) )
{
// Playlist file
Playlist::AppendPlaylistFile( szDir );
}
else
{
// Music file
TCHAR * szKeep = new TCHAR[ uDirLen + 1 ];
memcpy( szKeep, szDir, uDirLen * sizeof( TCHAR ) );
szKeep[ uDirLen ] = TEXT( '\0' );
playlist->PushBack( szKeep );
}
}
else
{
// \0 -> Several files
int iFileLen;
while( *szFileWalk != TEXT( '\0' ) )
{
iFileLen = ( int )_tcslen( szFileWalk );
if( !iFileLen ) return;
TCHAR * szKeep = new TCHAR[ uDirLen + 1 + iFileLen + 1 ];
memcpy( szKeep, szDir, uDirLen * sizeof( TCHAR ) );
szKeep[ uDirLen ] = TEXT( '\\' );
memcpy( szKeep + uDirLen + 1, szFileWalk, iFileLen * sizeof( TCHAR ) );
szKeep[ uDirLen + 1 + iFileLen ] = TEXT( '\0' );
if( !_tcsncmp( szKeep + uDirLen + 1 + iFileLen - 3, TEXT( "m3u" ), 3 ) )
{
// Playlist file
Playlist::AppendPlaylistFile( szKeep );
delete [] szKeep;
}
else
{
// Music file
playlist->PushBack( szKeep );
}
szFileWalk += iFileLen + 1;
}
}
}
+26
View File
@@ -0,0 +1,26 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_ADD_FILES_H
#define PA_ADD_FILES_H
#include "Global.h"
void AddFiles();
#endif // PA_ADD_FILES_H
+687
View File
@@ -0,0 +1,687 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// Include and declarations, definitions
////////////////////////////////////////////////////////////////////////////////
#include "Config.h"
#include "Console.h"
#include <map>
using namespace std;
map<TCHAR *, ConfVar *> * conf_map = NULL;
TCHAR * szIniPath = NULL;
const TCHAR * SECTION = TEXT( "Plainamp" );
// ============================================================================
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfVar::ConfVar( TCHAR * szKey, ConfMode mode )
{
// MessageBox( 0, TEXT( "no const @ ConfVar" ), TEXT( "" ), 0 );
//Console::Print("ConfVar::ConfVar(TCHAR) > Got <%s>\n", szKey);
// Init
const int iLen = ( int )_tcslen( szKey );
m_szKey = new TCHAR[ iLen + 1 ];
memcpy( m_szKey, szKey, iLen * sizeof( TCHAR ) );
m_szKey[ iLen ] = TEXT( '\0' );
m_bCopyKey = true;
m_Mode = mode;
m_bRead = false;
// Register
if( !conf_map ) conf_map = new map<TCHAR *, ConfVar *>;
conf_map->insert( pair<TCHAR *, ConfVar *>( m_szKey, this ) );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfVar::ConfVar( const TCHAR * szKey, ConfMode mode )
{
//Console::Print("ConfVar::ConfVar(const TCHAR) > Got <%s>\n", szKey);
// Init
m_szKey = ( TCHAR * )szKey;
m_bCopyKey = false;
m_Mode = mode;
m_bRead = false;
// Register
if( !conf_map ) conf_map = new map<TCHAR *, ConfVar *>;
conf_map->insert( pair<TCHAR *, ConfVar *>( m_szKey, this ) );
//Console::Print("ConfVar::ConfVar(const TCHAR) > Insert <%s>\n", ConfVar::m_szKey);
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfVar::~ConfVar()
{
if( m_bCopyKey && m_szKey ) delete [] m_szKey;
}
// =======================================================================================
// The line name is collected in ConfVar, then ConfBool gets the boolean
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfBool::ConfBool( bool * pbData, TCHAR * szKey, ConfMode mode, bool bDefault ) : ConfVar( szKey, mode )
{
// MessageBox( 0, TEXT( "no const @ ConfBool" ), TEXT( "" ), 0 );
//Console::Print("ConfBool(TCHAR) > Get <%s>\n", szKey);
m_pbData = pbData;
m_bDefault = bDefault;
// *pbData = bDefault;
}
// =======================================================================================
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfBool::ConfBool( bool * pbData, const TCHAR * szKey, ConfMode mode, bool bDefault ) : ConfVar( szKey, mode )
{
//Console::Print("ConfBool(TCHAR) > Get <%s>\n", szKey);
m_pbData = pbData;
m_bDefault = bDefault;
// *pbData = bDefault;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ConfBool::Read()
{
//Console::Print("ConfBool::Read() > Begin <m_bRead:%i> and <szIniPath:%s>\n", m_bRead, szIniPath);
if( m_bRead || !szIniPath ) return;
*m_pbData = ( GetPrivateProfileInt( SECTION, m_szKey, ( int )m_bDefault, szIniPath ) != 0 );
m_bRead = true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ConfBool::Write()
{
WritePrivateProfileString( SECTION, m_szKey, *m_pbData ? TEXT( "1" ) : TEXT( "0" ), szIniPath );
m_bRead = true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfInt::ConfInt( int * piData, TCHAR * szKey, ConfMode mode, int iDefault ) : ConfVar( szKey, mode )
{
MessageBox( 0, TEXT( "no const" ), TEXT( "" ), 0 );
m_piData = piData;
m_iDefault = iDefault;
// *piData = iDefault;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfInt::ConfInt( int * piData, const TCHAR * szKey, ConfMode mode, int iDefault ) : ConfVar( szKey, mode )
{
m_piData = piData;
m_iDefault = iDefault;
// *piData = iDefault;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ConfInt::Read()
{
if( m_bRead || !szIniPath ) return;
*m_piData = GetPrivateProfileInt( SECTION, m_szKey, m_iDefault, szIniPath );
m_bRead = true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ConfInt::Write()
{
TCHAR szNumber[ 12 ] = TEXT( "" );
_stprintf( szNumber, TEXT( "%i" ), *m_piData );
WritePrivateProfileString( SECTION, m_szKey, szNumber, szIniPath );
m_bRead = true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfIntMinMax::ConfIntMinMax( int * piData, TCHAR * szKey, ConfMode mode, int iDefault, int iMin, int iMax ) : ConfInt( piData, szKey, mode, iDefault )
{
MessageBox( 0, TEXT( "no const" ), TEXT( "" ), 0 );
m_iMin = iMin;
m_iMax = iMax;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfIntMinMax::ConfIntMinMax( int * piData, const TCHAR * szKey, ConfMode mode, int iDefault, int iMin, int iMax ) : ConfInt( piData, szKey, mode, iDefault )
{
m_iMin = iMin;
m_iMax = iMax;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfWinPlaceCallback::ConfWinPlaceCallback( WINDOWPLACEMENT * pwpData, TCHAR * szKey, RECT * prDefault, ConfCallback fpCallback ) : ConfVar( szKey, CONF_MODE_INTERNAL )
{
MessageBox( 0, TEXT( "no const" ), TEXT( "" ), 0 );
m_pwpData = pwpData;
m_prDefault = prDefault;
m_fpCallback = fpCallback;
pwpData->length = sizeof( WINDOWPLACEMENT );
pwpData->flags = 0;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfWinPlaceCallback::ConfWinPlaceCallback( WINDOWPLACEMENT * pwpData, const TCHAR * szKey, RECT * prDefault, ConfCallback fpCallback ) : ConfVar( szKey, CONF_MODE_INTERNAL )
{
m_pwpData = pwpData;
m_prDefault = prDefault;
m_fpCallback = fpCallback;
pwpData->length = sizeof( WINDOWPLACEMENT );
pwpData->flags = 0;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ConfWinPlaceCallback::Read()
{
if( m_bRead || !szIniPath ) return;
POINT ptMinPosition = { -1, -1 };
POINT ptMaxPosition = { -GetSystemMetrics( SM_CXBORDER ), -GetSystemMetrics( SM_CYBORDER ) };
m_pwpData->length = sizeof( WINDOWPLACEMENT );
m_pwpData->flags = 0;
m_pwpData->ptMinPosition = ptMinPosition;
m_pwpData->ptMaxPosition = ptMaxPosition;
TCHAR szOut[ 111 ] = TEXT( "" );
int iChars = GetPrivateProfileString( SECTION, m_szKey, TEXT( "" ), szOut, 110, szIniPath );
bool bApplyDefault = true;
if( iChars )
{
int iFields = _stscanf(
szOut,
TEXT( "(%u,(%i,%i,%i,%i))" ),
&m_pwpData->showCmd,
&m_pwpData->rcNormalPosition.left,
&m_pwpData->rcNormalPosition.top,
&m_pwpData->rcNormalPosition.right,
&m_pwpData->rcNormalPosition.bottom
);
if( iFields == 5 )
{
bApplyDefault = false;
}
}
if( bApplyDefault )
{
m_pwpData->showCmd = SW_SHOWNORMAL;
m_pwpData->rcNormalPosition = *m_prDefault;
}
m_bRead = true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ConfWinPlaceCallback::Write()
{
// Refresh data
if( m_fpCallback ) m_fpCallback( this );
TCHAR szData[ 111 ] = TEXT( "" );
_stprintf(
szData,
TEXT( "(%u,(%i,%i,%i,%i))" ),
m_pwpData->showCmd,
m_pwpData->rcNormalPosition.left,
m_pwpData->rcNormalPosition.top,
m_pwpData->rcNormalPosition.right,
m_pwpData->rcNormalPosition.bottom
);
WritePrivateProfileString( SECTION, m_szKey, szData, szIniPath );
m_bRead = true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfBandInfoCallback::ConfBandInfoCallback( BandInfo * pbiData, TCHAR * szKey, BandInfo * pbiDefault, ConfCallback fpCallback ) : ConfVar( szKey, CONF_MODE_INTERNAL )
{
MessageBox( 0, TEXT( "no const" ), TEXT( "" ), 0 );
m_pbiData = pbiData;
m_pbiDefault = pbiDefault;
m_fpCallback = fpCallback;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfBandInfoCallback::ConfBandInfoCallback( BandInfo * pbiData, const TCHAR * szKey, BandInfo * pbiDefault, ConfCallback fpCallback ) : ConfVar( szKey, CONF_MODE_INTERNAL )
{
m_pbiData = pbiData;
m_pbiDefault = pbiDefault;
m_fpCallback = fpCallback;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ConfBandInfoCallback::Read()
{
if( m_bRead || !szIniPath ) return;
int iBreak;
int iVisible;
TCHAR szOut[ 91 ] = TEXT( "" );
int iChars = GetPrivateProfileString( SECTION, m_szKey, TEXT( "" ), szOut, 90, szIniPath );
bool bApplyDefault = true;
if( iChars )
{
int iFields = _stscanf(
szOut,
TEXT( "(%i,%i,%i,%i)" ),
&m_pbiData->m_iIndex,
&m_pbiData->m_iWidth,
&iBreak,
&iVisible
);
if( iFields == 4 )
{
m_pbiData->m_bBreak = ( iBreak != 0 );
m_pbiData->m_bVisible = ( iVisible != 0 );
bApplyDefault = false;
}
}
if( bApplyDefault )
{
*m_pbiData = *m_pbiDefault;
}
m_bRead = true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ConfBandInfoCallback::Write()
{
// Refresh data
if( m_fpCallback ) m_fpCallback( this );
TCHAR szData[ 91 ] = TEXT( "" );
_stprintf(
szData,
TEXT( "(%i,%i,%i,%i)" ),
m_pbiData->m_iIndex,
m_pbiData->m_iWidth,
( int )m_pbiData->m_bBreak,
( int )m_pbiData->m_bVisible
);
WritePrivateProfileString( SECTION, m_szKey, szData, szIniPath );
m_bRead = true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool ConfBandInfoCallback::Apply( HWND hRebar, int iBandId )
{
const int iOldIndex = ( int )SendMessage( hRebar, RB_IDTOINDEX, iBandId, 0 );
if( iOldIndex == -1 ) return false;
int & iNewIndex = m_pbiData->m_iIndex;
if( iOldIndex != iNewIndex )
{
// Move band
if( !SendMessage( hRebar, RB_MOVEBAND, iOldIndex, iNewIndex ) )
{
return false;
}
}
REBARBANDINFO rbbi;
rbbi.cbSize = sizeof( REBARBANDINFO );
rbbi.fMask = RBBIM_STYLE;
// Get current info
if( !SendMessage( hRebar, RB_GETBANDINFO, iNewIndex, ( LPARAM )&rbbi ) )
{
return false;
}
rbbi.fMask = RBBIM_SIZE | RBBIM_STYLE;
rbbi.cx = m_pbiData->m_iWidth;
if( ( rbbi.fStyle & RBBS_BREAK ) == RBBS_BREAK )
{
if( !m_pbiData->m_bBreak ) rbbi.fStyle -= RBBS_BREAK;
}
else
{
if( m_pbiData->m_bBreak ) rbbi.fStyle |= RBBS_BREAK;
}
// Update info
if( !SendMessage( hRebar, RB_SETBANDINFO, iNewIndex, ( LPARAM )&rbbi ) )
{
return false;
}
// Show/hide band
if( !SendMessage( hRebar, RB_SHOWBAND, iNewIndex, m_pbiData->m_bVisible ? TRUE : FALSE ) )
{
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfString::ConfString( TCHAR * szData, TCHAR * szKey, ConfMode mode, TCHAR * szDefault, int iMaxLen ) : ConfVar( szKey, mode )
{
MessageBox( 0, TEXT( "no const" ), TEXT( "" ), 0 );
m_szData = szData;
m_szDefault = szDefault;
m_iMaxLen = iMaxLen;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfString::ConfString( TCHAR * szData, const TCHAR * szKey, ConfMode mode, TCHAR * szDefault, int iMaxLen ) : ConfVar( szKey, mode )
{
m_szData = szData;
m_szDefault = szDefault;
m_iMaxLen = iMaxLen;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ConfString::Read()
{
//Console::Print( "ConfString::Read() > Begin\n");
if( m_bRead || !szIniPath ) return;
GetPrivateProfileString( SECTION, m_szKey, m_szDefault, m_szData, m_iMaxLen, szIniPath );
//Console::Print( "ConfString::Read() > GetPrivateProfileString <%s> <%s> <%s>\n", m_szKey, m_szData, szIniPath);
m_bRead = true;
}
// =======================================================================================
// I don't use this
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ConfString::Write()
{
/*
WritePrivateProfileString( SECTION, m_szKey, m_szData, szIniPath );
m_bRead = true;
*/
}
// =======================================================================================
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfCurDir::ConfCurDir( TCHAR * szData, TCHAR * szKey ) : ConfString( szData, szKey,
CONF_MODE_INTERNAL, TEXT( "C:\\" ), MAX_PATH )
{
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
ConfCurDir::ConfCurDir( TCHAR * szData, const TCHAR * szKey ) : ConfString( szData, szKey,
CONF_MODE_INTERNAL, TEXT( "C:\\" ), MAX_PATH )
{
}
////////////////////////////////////////////////////////////////////////////////
/* IMPORTANT: This SetCurrentDirectory() has to be disabled or we change the relative paths
for the entire application */
////////////////////////////////////////////////////////////////////////////////
void ConfCurDir::Read()
{
ConfString::Read();
// Apply
//SetCurrentDirectory( m_szData );
//Console::Print("ConfCurDir::Read > End <%s>\n", m_szData);
}
// ==============================================================================
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ConfCurDir::Write()
{
// Refresh
GetCurrentDirectory( MAX_PATH, m_szData ); // Note: without trailing slash
// MessageBox( 0, m_szData, TEXT( "CurDir" ), 0 );
//Console::Print("ConfCurDir::Read <%s>\n", m_szData);
ConfString::Write();
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void Conf::Init()
{
if( szIniPath ) return;
// =======================================================================================
// Find the right ini file
// Long filename
szIniPath = new TCHAR[ _MAX_PATH ];
TCHAR szFull[ _MAX_PATH ] = TEXT( "" );
TCHAR szDrive[ _MAX_DRIVE ] = TEXT( "" );
TCHAR szDir[ _MAX_DIR ] = TEXT( "" );
// ---------------------------------------------------------------------------------------
// We place the full path in szFull
//GetModuleFileName( hInstance, szFull, _MAX_PATH );
GetModuleFileName( NULL, szFull, _MAX_PATH ); // No don't use that
// ---------------------------------------------------------------------------------------
_tsplitpath( szFull, szDrive, szDir, NULL, NULL );
// Convert short to long path
GetLongPathName( szDir, szDir, _MAX_DIR );
// ---------------------------------------------------------------------------------------
// We place information about the file in fd
// ---------------------------------------------------------------------------------------
// Convert short to long file
WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile( szFull, &fd );
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Convert File.exe to File.ini
// ---------------------------------------------------------------------------------------
// Search last dot
TCHAR * szSearch = fd.cFileName + _tcslen( fd.cFileName ) - 1;
while( ( *szSearch != TEXT( '.' ) ) && ( szSearch > fd.cFileName ) )
{
szSearch--;
}
// ---------------------------------------------------------------------------------------
// Replace extension
_tcscpy( szSearch, TEXT( ".ini" ) );
// ---------------------------------------------------------------------------------------
// Copy full filename
//_sntprintf( szIniPath, _MAX_PATH, TEXT( "%s%s%s" ), szDrive, szDir, fd.cFileName );
_sntprintf( szIniPath, _MAX_PATH, TEXT( "%s%s%s" ), szDrive, szDir, TEXT( "Plainamp.ini" ) );
Console::Print("DLL > Ini path <%s>\n", szIniPath);
// =======================================================================================
// ---------------------------------------------------------------------------------------
// Read all settings in it
// ---------------------------------------------------------------------------------------
// Read all (original comment)
map<TCHAR *, ConfVar *>::iterator iter = conf_map->begin();
// =======================================================================================
// This will lead us to the Read() function earlier in this file. For example ConfBool::Read()
while( iter != conf_map->end() )
{
/* By default there was a SetCurrentDirectory() here that would affect the entire process,
exe and everything. It is disabled now. */
iter->second->Read();
iter++;
}
// =======================================================================================
// ---------------------------------------------------------------------------------------
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void Conf::Write()
{
if( !szIniPath ) return;
map<TCHAR *, ConfVar *>::iterator iter = conf_map->begin();
while( iter != conf_map->end() )
{
iter->second->Write();
iter++;
}
}
+239
View File
@@ -0,0 +1,239 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_CONFIG_H
#define PA_CONFIG_H
#include "Global.h"
#include "OutputPlugin.h"
namespace Conf
{
//void Init( HINSTANCE hInstance );
void Init( );
void Write();
};
enum ConfMode
{
CONF_MODE_INTERNAL, // Will not be shown to the user
CONF_MODE_PUBLIC
};
class ConfVar;
typedef void ( * ConfCallback )( ConfVar * var );
struct BandInfo
{
int m_iIndex;
int m_iWidth;
bool m_bBreak;
bool m_bVisible;
};
////////////////////////////////////////////////////////////////////////////////
/// Config container
////////////////////////////////////////////////////////////////////////////////
class ConfVar
{
public:
ConfVar( TCHAR * szKey, ConfMode mode );
ConfVar( const TCHAR * szKey, ConfMode mode );
~ConfVar();
protected:
TCHAR * m_szKey; ///< Unique identifier
ConfMode m_Mode; ///< Mode/visibility
bool m_bRead; ///< Initilization flag
virtual void Read() = 0;
virtual void Write() = 0;
// virtual void Backup() = 0; ///< Creates a backup and deletes old backup if it exists
// virtual void Restore() = 0; ///< Restores settings from backup and destroys the backup
private:
bool m_bCopyKey; ///< Keyname is copy (has to be freed on destruction)
//friend void Conf::Init( HINSTANCE hInstance );
friend void Conf::Init( );
friend void Conf::Write();
};
////////////////////////////////////////////////////////////////////////////////
/// Boolean config container
////////////////////////////////////////////////////////////////////////////////
class ConfBool : public ConfVar
{
public:
ConfBool( bool * pbData, TCHAR * szKey, ConfMode mode, bool bDefault );
ConfBool( bool * pbData, const TCHAR * szKey, ConfMode mode, bool bDefault );
private:
bool * m_pbData; ///< Target
bool m_bDefault; ///< Default value
void Read();
void Write();
friend OutputPlugin::OutputPlugin( TCHAR * szDllpath, bool bKeepLoaded );
};
////////////////////////////////////////////////////////////////////////////////
/// Integer config container
////////////////////////////////////////////////////////////////////////////////
class ConfInt : public ConfVar
{
public:
ConfInt( int * piData, TCHAR * szKey, ConfMode mode, int iDefault );
ConfInt( int * piData, const TCHAR * szKey, ConfMode mode, int iDefault );
protected:
int * m_piData;
int m_iDefault;
void Read();
void Write();
};
////////////////////////////////////////////////////////////////////////////////
/// Integer config container with restricted range
////////////////////////////////////////////////////////////////////////////////
class ConfIntMinMax : public ConfInt
{
public:
ConfIntMinMax( int * piData, TCHAR * szKey, ConfMode mode, int iDefault, int iMin, int iMax );
ConfIntMinMax( int * piData, const TCHAR * szKey, ConfMode mode, int iDefault, int iMin, int iMax );
// bool IsValid() { return ( ( *m_piData >= m_iMin ) && ( *m_piData <= m_iMax ) ); }
inline bool IsMin() { return ( *m_piData == m_iMin ); }
inline bool IsMax() { return ( *m_piData == m_iMax ); }
inline void MakeValidDefault() { if( ( *m_piData < m_iMin ) || ( *m_piData > m_iMax ) ) *m_piData = m_iDefault; }
inline void MakeValidPull() { if( *m_piData < m_iMin ) *m_piData = m_iMin; else if( *m_piData > m_iMax ) *m_piData = m_iMax; }
private:
int m_iMin;
int m_iMax;
void Read() { ConfInt::Read(); MakeValidPull(); }
};
////////////////////////////////////////////////////////////////////////////////
/// Window placement config container
///
/// The callback funtion is called on write()
/// so the data written is up to date.
////////////////////////////////////////////////////////////////////////////////
class ConfWinPlaceCallback : public ConfVar
{
public:
ConfWinPlaceCallback( WINDOWPLACEMENT * pwpData, TCHAR * szKey, RECT * prDefault, ConfCallback fpCallback );
ConfWinPlaceCallback( WINDOWPLACEMENT * pwpData, const TCHAR * szKey, RECT * prDefault, ConfCallback fpCallback );
inline void TriggerCallback() { if( m_fpCallback ) m_fpCallback( this ); }
inline void RemoveCallback() { m_fpCallback = NULL; }
private:
WINDOWPLACEMENT * m_pwpData;
RECT * m_prDefault;
ConfCallback m_fpCallback;
void Read();
void Write();
};
////////////////////////////////////////////////////////////////////////////////
/// Rebar band info config container
///
/// The callback funtion is called on write()
/// so the data written is up to date.
////////////////////////////////////////////////////////////////////////////////
class ConfBandInfoCallback : public ConfVar
{
public:
ConfBandInfoCallback( BandInfo * pbiData, TCHAR * szKey, BandInfo * pbiDefault, ConfCallback fpCallback );
ConfBandInfoCallback( BandInfo * pbiData, const TCHAR * szKey, BandInfo * pbiDefault, ConfCallback fpCallback );
inline void TriggerCallback() { if( m_fpCallback ) m_fpCallback( this ); }
inline void RemoveCallback() { m_fpCallback = NULL; }
bool Apply( HWND hRebar, int iBandId );
private:
BandInfo * m_pbiData;
BandInfo * m_pbiDefault;
ConfCallback m_fpCallback;
void Read();
void Write();
};
////////////////////////////////////////////////////////////////////////////////
/// String config container
////////////////////////////////////////////////////////////////////////////////
class ConfString : public ConfVar
{
public:
ConfString( TCHAR * szData, TCHAR * szKey, ConfMode mode, TCHAR * szDefault, int iMaxLen );
ConfString( TCHAR * szData, const TCHAR * szKey, ConfMode mode, TCHAR * szDefault, int iMaxLen );
protected:
TCHAR * m_szData;
int m_iMaxLen;
TCHAR * m_szDefault;
void Read();
void Write();
};
////////////////////////////////////////////////////////////////////////////////
/// Current directory config container
////////////////////////////////////////////////////////////////////////////////
class ConfCurDir : public ConfString
{
public:
ConfCurDir( TCHAR * szData, TCHAR * szKey );
ConfCurDir( TCHAR * szData, const TCHAR * szKey );
private:
void Read();
void Write();
};
#endif // PA_CONFIG_H
+228
View File
@@ -0,0 +1,228 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Console.h"
#include "Font.h"
#include "Main.h"
#include "Config.h"
#include <time.h>
HWND WindowConsole = NULL; // extern
int iNext = 0;
const int iMaxEntries = 10000;
WNDPROC WndprocConsoleBackup = NULL;
LRESULT CALLBACK WndprocConsole( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
bool bConsoleVisible;
WINDOWPLACEMENT WinPlaceConsole;
void WinPlaceConsoleCallback( ConfVar * var )
{
if( !IsWindow( WindowConsole ) ) return;
GetWindowPlacement( WindowConsole, &WinPlaceConsole );
// MSDN: If the window identified by the hWnd parameter
// is maximized, the showCmd member is SW_SHOWMAXIMIZED.
// If the window is minimized, showCmd is SW_SHOWMINIMIZED.
// Otherwise, it is SW_SHOWNORMAL.
if( !bConsoleVisible )
{
WinPlaceConsole.showCmd = SW_HIDE;
}
}
RECT rConsoleDefault = { 50, 400, 450, 700 };
ConfWinPlaceCallback cwpcWinPlaceConsole(
&WinPlaceConsole,
TEXT( "WinPlaceConsole" ),
&rConsoleDefault,
WinPlaceConsoleCallback
);
////////////////////////////////////////////////////////////////////////////////
/// Creates the console window.
/// Size and visibility is used from config.
///
/// @return Success flag
////////////////////////////////////////////////////////////////////////////////
bool Console::Create()
{
WindowConsole = CreateWindowEx(
WS_EX_TOOLWINDOW | // DWORD dwExStyle
WS_EX_CLIENTEDGE, //
TEXT( "LISTBOX" ), // LPCTSTR lpClassName
TEXT( "Console" ), // LPCTSTR lpWindowName
WS_VSCROLL | // DWORD dwStyle
LBS_DISABLENOSCROLL | //
LBS_EXTENDEDSEL | //
LBS_HASSTRINGS | //
LBS_NOTIFY | //
LBS_NOINTEGRALHEIGHT | //
WS_POPUP | //
WS_OVERLAPPEDWINDOW, //
rConsoleDefault.left, // int x
rConsoleDefault.top, // int y
rConsoleDefault.right - rConsoleDefault.left, // int nWidth
rConsoleDefault.bottom - rConsoleDefault.top, // int nHeight
WindowMain, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
if( !WindowConsole ) return false;
// A blank line at the bottom will give us more space
SendMessage( WindowConsole, LB_INSERTSTRING, 0, ( LPARAM )TEXT( "" ) );
Font::Apply( WindowConsole );
bConsoleVisible = ( WinPlaceConsole.showCmd != SW_HIDE );
SetWindowPlacement( WindowConsole, &WinPlaceConsole );
// Exchange window procedure
WndprocConsoleBackup = ( WNDPROC )GetWindowLong( WindowConsole, GWL_WNDPROC );
if( WndprocConsoleBackup != NULL )
{
SetWindowLong( WindowConsole, GWL_WNDPROC, ( LONG )WndprocConsole );
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// Destroys the console window.
///
/// @return Success flag
////////////////////////////////////////////////////////////////////////////////
bool Console::Destroy()
{
if( !WindowConsole ) return false;
DestroyWindow( WindowConsole );
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// Pops up the console window.
///
/// @return Success flag
////////////////////////////////////////////////////////////////////////////////
bool Console::Popup()
{
if( !WindowConsole ) return false;
if( !IsWindowVisible( WindowConsole ) )
{
ShowWindow( WindowConsole, SW_SHOW );
}
SetActiveWindow( WindowConsole );
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// Adds a new entry at the end/bottom
///
/// @param szText Log entry
/// @return Success flag
////////////////////////////////////////////////////////////////////////////////
bool Console::Append( TCHAR * szText )
{
if( !WindowConsole ) return false;
if( iNext > iMaxEntries - 1 )
{
SendMessage(
WindowConsole,
LB_DELETESTRING,
0,
0
);
iNext--;
}
const int uTextLen = ( int )_tcslen( szText );
TCHAR * szBuffer = new TCHAR[ 11 + uTextLen + 1 ];
time_t now_time_t = time( NULL );
struct tm * now_tm = localtime( &now_time_t );
_tcsftime( szBuffer, 12, TEXT( "%H:%M:%S " ), now_tm );
memcpy( szBuffer + 11, szText, uTextLen * sizeof( TCHAR ) );
szBuffer[ 11 + uTextLen ] = TEXT( '\0' );
SendMessage( WindowConsole, LB_INSERTSTRING, iNext, ( LPARAM )szBuffer );
SendMessage( WindowConsole, LB_SETSEL, FALSE, -1 );
SendMessage( WindowConsole, LB_SETSEL, TRUE, iNext );
SendMessage( WindowConsole, LB_SETTOPINDEX, iNext, 0 );
iNext++;
delete [] szBuffer;
return true;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndprocConsole( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
switch( message )
{
/*
case WM_CTLCOLORLISTBOX:
if( ( HWND )lp == WindowConsole )
{
SetBkColor (( HDC )wp, GetSysColor(COLOR_3DFACE));
return ( LRESULT )GetSysColorBrush(COLOR_3DFACE);
}
break;
*/
case WM_SYSCOMMAND:
// Hide instead of closing
if( ( wp & 0xFFF0 ) == SC_CLOSE )
{
ShowWindow( hwnd, SW_HIDE );
return 0;
}
break;
case WM_DESTROY:
cwpcWinPlaceConsole.TriggerCallback();
cwpcWinPlaceConsole.RemoveCallback();
break;
case WM_SHOWWINDOW:
bConsoleVisible = ( wp == TRUE );
break;
}
return CallWindowProc( WndprocConsoleBackup, hwnd, message, wp, lp );
}
+40
View File
@@ -0,0 +1,40 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_CONSOLE_H
#define PA_CONSOLE_H
#include "Global.h"
extern HWND WindowConsole;
////////////////////////////////////////////////////////////////////////////////
/// Logging console window
////////////////////////////////////////////////////////////////////////////////
namespace Console
{
bool Create();
bool Destroy();
bool Popup();
bool Append( TCHAR * szText );
}
#endif // PA_CONSOLE_H
+136
View File
@@ -0,0 +1,136 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "DspModule.h"
#include "Unicode.h"
DspModule ** active_dsp_mods = NULL; // extern
int active_dsp_count = 0; // extern
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
DspModule::DspModule( char * szName, int iIndex, winampDSPModule * mod, DspPlugin * plugin )
{
iArrayIndex = -1;
iNameLen = ( int )strlen( szName );
this->szName = new TCHAR[ iNameLen + 1 ];
ToTchar( this->szName, szName, iNameLen );
this->szName[ iNameLen ] = TEXT( '\0' );
this->iIndex = iIndex;
this->mod = mod;
this->plugin = plugin;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool DspModule::Start( int iIndex )
{
if( !mod ) return false;
if( iArrayIndex != -1 ) return false;
if( !mod->Init ) return false;
if( mod->Init( mod ) != 0 ) return false;
////////////////////////////////////////////////////////////////////////////////
DspLock.Enter();
////////////////////////////////////////////////////////////////////////////////
if( !active_dsp_count )
{
active_dsp_mods = new DspModule * [ 1 ];
active_dsp_mods[ 0 ] = this;
iArrayIndex = 0;
}
else
{
if( iIndex < 0 )
iIndex = 0;
else if( iIndex > active_dsp_count )
iIndex = active_dsp_count;
DspModule ** new_active_dsp_mods = new DspModule * [ active_dsp_count + 1 ];
memcpy( new_active_dsp_mods, active_dsp_mods, iIndex * sizeof( DspModule * ) );
memcpy( new_active_dsp_mods + iIndex + 1, active_dsp_mods + iIndex, ( active_dsp_count - iIndex ) * sizeof( DspModule * ) );
for( int i = iIndex + 1; i < active_dsp_count + 1; i++ )
{
new_active_dsp_mods[ i ]->iArrayIndex = i;
}
new_active_dsp_mods[ iIndex ] = this;
iArrayIndex = iIndex;
delete [] active_dsp_mods;
active_dsp_mods = new_active_dsp_mods;
}
active_dsp_count++;
////////////////////////////////////////////////////////////////////////////////
DspLock.Leave();
////////////////////////////////////////////////////////////////////////////////
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool DspModule::Stop()
{
if( !mod ) return false;
if( iArrayIndex == -1 ) return false;
if( !mod->Quit ) return true;
////////////////////////////////////////////////////////////////////////////////
DspLock.Enter();
////////////////////////////////////////////////////////////////////////////////
for( int i = iArrayIndex; i < active_dsp_count - 1; i++ )
{
active_dsp_mods[ i ] = active_dsp_mods[ i + 1 ];
active_dsp_mods[ i ]->iArrayIndex = i;
}
active_dsp_count--;
////////////////////////////////////////////////////////////////////////////////
DspLock.Leave();
////////////////////////////////////////////////////////////////////////////////
mod->Quit( mod );
iArrayIndex = -1;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool DspModule::Config()
{
if( !mod ) return false;
if( iArrayIndex == -1 ) return false;
if( !mod->Config ) return false;
mod->Config( mod );
return true;
}
+67
View File
@@ -0,0 +1,67 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_DSP_MODULE_H
#define PA_DSP_MODULE_H
#include "Global.h"
#include "DspPlugin.h"
#include "Winamp/Dsp.h"
class DspModule;
class DspPlugin;
extern DspModule ** active_dsp_mods;
extern int active_dsp_count;
////////////////////////////////////////////////////////////////////////////////
/// Winamp DSP module wrapper
////////////////////////////////////////////////////////////////////////////////
class DspModule
{
public:
inline bool IsActive() { return ( iArrayIndex != -1 ); }
inline TCHAR * GetName() { return szName; }
inline int GetNameLen() { return iNameLen; }
DspModule( char * szName, int iIndex, winampDSPModule * mod, DspPlugin * plugin );
// DspModule( wchar_t * szName, int iIndex, winampVisModule * mod, VisPlugin * plugin );
bool Start( int iIndex );
bool Stop();
bool Config();
private:
int iArrayIndex;
TCHAR * szName;
int iNameLen;
int iIndex;
winampDSPModule * mod;
DspPlugin * plugin;
friend int dsp_dosamples( short int * samples, int numsamples, int bps, int nch, int srate );
};
#endif // PA_DSP_MODULE_H
+186
View File
@@ -0,0 +1,186 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "DspPlugin.h"
#include "Main.h"
#include "Unicode.h"
#include "Console.h"
vector <DspPlugin *> dsp_plugins; // extern
Lock DspLock = Lock( TEXT( "PLAINAMP_DSP_LOCK" ) ); // extern
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
DspPlugin::DspPlugin( TCHAR * szDllpath, bool bKeepLoaded ) : Plugin( szDllpath )
{
header = NULL;
if( !Load() )
{
return;
}
if( !bKeepLoaded )
{
Unload();
}
dsp_plugins.push_back( this );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool DspPlugin::Load()
{
if( IsLoaded() ) return true;
// (1) Load DLL
hDLL = LoadLibrary( GetFullpath() );
if( !hDLL ) return false;
// (2) Find export
WINAMP_DSP_GETTER winampGetDSPHeader2 =
( WINAMP_DSP_GETTER )GetProcAddress( hDLL, "winampDSPGetHeader2" );
if( winampGetDSPHeader2 == NULL )
{
FreeLibrary( hDLL );
hDLL = NULL;
return false;
}
// (3) Get header
header = winampGetDSPHeader2();
if( header == NULL )
{
FreeLibrary( hDLL );
hDLL = NULL;
return false;
}
////////////////////////////////////////////////////////////////////////////////
// Forget old modules or we get them twice
if( !modules.empty() )
{
modules.clear();
}
////////////////////////////////////////////////////////////////////////////////
if( !szName )
{
// Note: The prefix is not removed to hide their
// origin at Nullsoft! It just reads easier.
if( !strnicmp( header->description, "nullsoft ", 9 ) )
{
header->description += 9;
}
iNameLen = ( int )strlen( header->description );
szName = new TCHAR[ iNameLen + 1 ];
ToTchar( szName, header->description, iNameLen );
szName[ iNameLen ] = TEXT( '\0' );
}
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Loading <%s>, %s" ), GetFilename(), szName );
Console::Append( szBuffer );
// (4) Get modules
winampDSPModule * mod;
int iFound = 0;
while( true )
{
mod = header->getModule( iFound );
if( !mod ) break;
// (4a) Modify module
mod->hDllInstance = hDLL;
mod->hwndParent = WindowMain;
// (4b) Add module to list
DspModule * dspmod = new DspModule(
mod->description, // char * szName
iFound, // UINT uIndex
mod, // winampDspModule * mod
this // DspPlugin * plugin
);
modules.push_back( dspmod );
iFound++;
_stprintf( szBuffer, TEXT( " %s" ), dspmod->GetName() );
Console::Append( szBuffer );
}
Console::Append( TEXT( " " ) );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool DspPlugin::Unload()
{
if( !IsLoaded() ) return true;
if( IsActive() ) return false;
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Unloading <%s>" ), GetFilename() );
Console::Append( szBuffer );
Console::Append( TEXT( " " ) );
printf( ">>>Unloading <%s>\n" , GetFilename() );
header = NULL;
/*
TODO
DspModule * walk;
vector <DspModule *>::iterator iter = modules.begin();
while( iter != modules.end() )
{
walk = *iter;
delete [] walk->szName;
delete walk;
iter++;
}
*/
FreeLibrary( hDLL );
hDLL = NULL;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool DspPlugin::IsActive()
{
vector <DspModule *>::iterator iter = modules.begin();
while( iter != modules.end() )
{
if( ( *iter )->IsActive() ) return true;
iter++;
}
return false;
}
+69
View File
@@ -0,0 +1,69 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_DSP_PLUGIN_H
#define PA_DSP_PLUGIN_H
#include "Global.h"
#include "Plugin.h"
#include "Winamp/Dsp.h"
#include "Lock.h"
#include "DspModule.h"
#include <vector>
using namespace std;
typedef winampDSPHeader * ( * WINAMP_DSP_GETTER )( void );
class DspModule;
class DspPlugin;
extern vector <DspPlugin *> dsp_plugins;
extern Lock DspLock;
////////////////////////////////////////////////////////////////////////////////
/// Winamp DSP plugin wrapper
////////////////////////////////////////////////////////////////////////////////
class DspPlugin : public Plugin
{
public:
DspPlugin( TCHAR * szDllpath, bool bKeepLoaded );
bool Load();
bool Unload();
TCHAR * GetTypeString() { return TEXT( "DSP" ); }
int GetTypeStringLen() { return 3; }
PluginType GetType() { return PLUGIN_TYPE_DSP; }
bool IsActive();
private:
winampDSPHeader * header;
vector<DspModule *> modules;
friend class DspModule;
friend void ContextMenuDsp( DspPlugin * dsp, POINT * p );
};
#endif // PA_DSP_PLUGIN_H
+455
View File
@@ -0,0 +1,455 @@
/*//////////////////////////////////////////////////////////////////////////////
// ExtraMessageBox
//
// Copyright © 2006 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
//////////////////////////////////////////////////////////////////////////////*/
/*
TODO
* realign/recenter after height change
* tab stop order when adding buttons
* offer extra callback?
* auto click timer (one button after XXX seconds)
* allow several checkboxes? radio buttons?
MB_YESNO
MB_YESNOCANCEL
--> MB_YESNOALL
--> MB_YESNOCANCELALL
--> MB_DEFBUTTON5
--> IDNOALL
--> IDYESALL
*/
#include "Emabox.h"
#define FUNCTION_NORMAL 0
#define FUNCTION_EXTENDED 1
#define FUNCTION_INDIRECT 2
const int SPACE_UNDER_CHECKBOX = 10;
const int SPACE_EXTRA_BOTTOM = 4;
TCHAR * const szNeverAgain = TEXT( "Do not show again" );
TCHAR * const szRememberChoice = TEXT( "Remember my choice" );
DWORD dwTlsSlot = TLS_OUT_OF_INDEXES;
#ifdef EMA_AUTOINIT
int bEmaInitDone = 0;
#endif
struct StructEmaBoxData
{
int * bCheckState;
HHOOK hCBT; /* CBT hook handle */
WNDPROC WndprocMsgBoxBackup; /* Old wndproc */
UINT uType; /* Message box type */
HWND hCheck; /* Checkbox handle */
};
typedef struct StructEmaBoxData EmaBoxData;
void RectScreenToClient( const HWND h, RECT * const r )
{
POINT p;
RECT after;
p.x = r->left;
p.y = r->top;
ScreenToClient( h, &p );
after.left = p.x;
after.right = p.x + r->right - r->left;
after.top = p.y;
after.bottom = p.y + r->bottom - r->top;
memcpy( r, &after, sizeof( RECT ) );
}
LRESULT CALLBACK WndprocMsgBox( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
/* Find data */
EmaBoxData * const data = ( EmaBoxData * )TlsGetValue( dwTlsSlot );
switch( message )
{
case WM_COMMAND:
if( HIWORD( wp ) == BN_CLICKED )
{
if( !data->hCheck || ( ( HWND )lp != data->hCheck ) ) break;
{
const LRESULT res = SendMessage( ( HWND )lp, BM_GETSTATE, 0, 0 );
const int bCheckedAfter = ( ( res & BST_CHECKED ) == 0 );
/* Update external variable */
*( data->bCheckState ) = bCheckedAfter ? 1 : 0;
SendMessage( ( HWND )lp, BM_SETCHECK, ( bCheckedAfter ) ? BST_CHECKED : 0, 0 );
}
}
break;
case WM_INITDIALOG:
{
/* Add checkbox */
if( ( data->uType & MB_CHECKMASC ) != 0 )
{
int SPACE_OVER_CHECKBOX;
HDC hdc;
RECT rw; /* Window rect */
RECT rc; /* Client rect */
HWND hText; /* Message handle */
RECT rt; /* Message rect */
int iLabelHeight;
TCHAR * szCheckboxLabel; /* Checkbox label */
int iWindowWidthBefore;
int iWindowHeightBefore;
int iClientWidthBefore;
int iClientHeightBefore;
int iNeverAgainWidth;
int iNeverAgainHeight;
/* Get original window dimensions */
GetWindowRect( hwnd, &rw );
iWindowWidthBefore = rw.right - rw.left;
iWindowHeightBefore = rw.bottom - rw.top;
GetClientRect( hwnd, &rc );
iClientWidthBefore = rc.right - rc.left;
iClientHeightBefore = rc.bottom - rc.top;
{
/* Find handle of the text label */
HWND hFirstStatic;
HWND hSecondStatic;
hFirstStatic = FindWindowEx( hwnd, NULL, TEXT( "STATIC" ), NULL );
if( !hFirstStatic ) break;
hSecondStatic = FindWindowEx( hwnd, hFirstStatic, TEXT( "STATIC" ), NULL );
if( !hSecondStatic )
{
/* Only one static means no icon. */
/* So hFirstStatic must be the text window. */
hText = hFirstStatic;
}
else
{
TCHAR szBuf[ 2 ] = TEXT( "" );
if( !GetWindowText( hSecondStatic, szBuf, 2 ) ) break;
if( *szBuf != TEXT( '\0' ) )
{
/* Has text so it must be the label */
hText = hSecondStatic;
}
else
{
hText = hFirstStatic;
}
}
}
GetWindowRect( hText, &rt );
RectScreenToClient( hwnd, &rt );
iLabelHeight = rt.bottom - rt.top;
{
/* Get distance between label and the buttons */
HWND hAnyButton;
RECT rab;
hAnyButton = FindWindowEx( hwnd, NULL, TEXT( "BUTTON" ), NULL );
if( !hAnyButton ) break;
GetWindowRect( hAnyButton, &rab );
RectScreenToClient( hwnd, &rab );
SPACE_OVER_CHECKBOX = rab.top - rt.bottom;
}
szCheckboxLabel = ( data->uType & MB_CHECKNEVERAGAIN )
? EMA_TEXT_NEVER_AGAIN
: EMA_TEXT_REMEMBER_CHOICE;
/* Add checkbox */
data->hCheck = CreateWindow(
TEXT( "BUTTON" ),
szCheckboxLabel,
WS_CHILD |
WS_VISIBLE |
WS_TABSTOP |
BS_VCENTER |
BS_CHECKBOX,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
hwnd,
NULL,
GetModuleHandle( NULL ),
NULL
);
/* Set initial check state */
SendMessage( data->hCheck, BM_SETCHECK, *( data->bCheckState ) ? BST_CHECKED : 0, 0 );
{
/* Apply default font */
const int cyMenuSize = GetSystemMetrics( SM_CYMENUSIZE );
const int cxMenuSize = GetSystemMetrics( SM_CXMENUSIZE );
const HFONT hNewFont = ( HFONT )GetStockObject( DEFAULT_GUI_FONT );
HFONT hOldFont;
SIZE size;
SendMessage( data->hCheck, WM_SETFONT, ( WPARAM )hNewFont, ( LPARAM )TRUE );
hdc = GetDC( data->hCheck );
hOldFont = ( HFONT )SelectObject( hdc, GetStockObject( DEFAULT_GUI_FONT ) );
GetTextExtentPoint32( hdc, szCheckboxLabel, _tcslen( szCheckboxLabel ), &size );
SelectObject( hdc, hOldFont );
ReleaseDC( data->hCheck, hdc );
iNeverAgainWidth = cxMenuSize + size.cx + 1;
iNeverAgainHeight = ( cyMenuSize > size.cy ) ? cyMenuSize : size.cy;
}
MoveWindow(
data->hCheck,
( iClientWidthBefore - ( iNeverAgainWidth ) ) / 2,
rt.top + iLabelHeight + SPACE_OVER_CHECKBOX,
iNeverAgainWidth,
iNeverAgainHeight,
FALSE
);
{
/* Move all buttons down (except the checkbox) */
const int iDistance = iNeverAgainHeight + SPACE_UNDER_CHECKBOX;
HWND hLastButton = NULL;
RECT rb;
for( ; ; )
{
hLastButton = FindWindowEx( hwnd, hLastButton, TEXT( "BUTTON" ), NULL );
if( !hLastButton ) break;
if( hLastButton == data->hCheck ) continue;
GetWindowRect( hLastButton, &rb );
RectScreenToClient( hwnd, &rb );
MoveWindow( hLastButton, rb.left, rb.top + iDistance, rb.right - rb.left, rb.bottom - rb.top, FALSE );
}
/* Enlarge dialog */
MoveWindow( hwnd, rw.left, rw.top, iWindowWidthBefore, iWindowHeightBefore + iDistance + SPACE_EXTRA_BOTTOM, FALSE );
}
}
else
{
data->hCheck = NULL;
}
/* Modify close button */
switch( data->uType & MB_CLOSEMASK )
{
case MB_DISABLECLOSE:
{
const HMENU hSysMenu = GetSystemMenu( hwnd, FALSE );
EnableMenuItem( hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED );
}
break;
case MB_NOCLOSE:
{
const LONG style = GetWindowLong( hwnd, GWL_STYLE );
if( ( style & WS_SYSMENU ) == 0 ) break;
SetWindowLong( hwnd, GWL_STYLE, ( LONG )( style - WS_SYSMENU ) );
}
break;
}
}
break;
}
return CallWindowProc( data->WndprocMsgBoxBackup, hwnd, message, wp, lp );
}
/* int bFound = 0; */
LRESULT CALLBACK HookprocMsgBox( int code, WPARAM wp, LPARAM lp )
{
/* Get hook handle */
EmaBoxData * const data = ( EmaBoxData * )TlsGetValue( dwTlsSlot );
if( code == HCBT_CREATEWND )
{
/* MSDN says WE CANNOT TRUST "CBT_CREATEWND" */
/* so we use only the window handle */
/* and get the class name using "GetClassName". (-> Q106079) */
HWND hwnd = ( HWND )wp;
/* Check windowclass */
TCHAR szClass[ 7 ] = TEXT( "" );
GetClassName( hwnd, szClass, 7 );
if( !_tcscmp( szClass, TEXT( "#32770" ) ) )
{
/*
if( bFound )
{
return CallNextHookEx( hCBT, code, wp, lp );
}
bFound = 1;
*/
/* Exchange window procedure */
data->WndprocMsgBoxBackup = ( WNDPROC )GetWindowLong( hwnd, GWL_WNDPROC );
if( data->WndprocMsgBoxBackup != NULL )
{
SetWindowLong( hwnd, GWL_WNDPROC, ( LONG )WndprocMsgBox );
}
}
}
return CallNextHookEx( data->hCBT, code, wp, lp );
}
int ExtraAllTheSame( const HWND hWnd, const LPCTSTR lpText, const LPCTSTR lpCaption, const UINT uType, const WORD wLanguageId, const LPMSGBOXPARAMS lpMsgBoxParams, int * const pbCheckRes, const int iFunction )
{
EmaBoxData * data;
HHOOK hCBT;
int res;
#ifdef EMA_AUTOINIT
if( !bEmaInitDone )
{
EmaBoxLive();
bEmaInitDone = 1;
}
#endif
/* Create thread data */
data = ( EmaBoxData * )LocalAlloc( NONZEROLPTR, sizeof( EmaBoxData ) );
TlsSetValue( dwTlsSlot, data );
data->bCheckState = pbCheckRes;
data->uType = ( iFunction != FUNCTION_INDIRECT ) ? uType : lpMsgBoxParams->dwStyle;
/* Setup this-thread-only hook */
hCBT = SetWindowsHookEx( WH_CBT, &HookprocMsgBox, GetModuleHandle( NULL ), GetCurrentThreadId() );
switch( iFunction )
{
case FUNCTION_NORMAL:
res = MessageBox( hWnd, lpText, lpCaption, uType );
break;
case FUNCTION_EXTENDED:
res = MessageBoxEx( hWnd, lpText, lpCaption, uType, wLanguageId );
break;
case FUNCTION_INDIRECT:
res = MessageBoxIndirect( lpMsgBoxParams );
break;
}
/* Remove hook */
if( hCBT != NULL ) UnhookWindowsHookEx( hCBT );
/* Destroy thread data */
LocalFree( ( HLOCAL )data );
return res;
}
int EmaBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType, int * pbCheckRes )
{
/* Check extra flags */
if( ( uType & MB_EXTRAMASC ) == 0 )
{
/* No extra */
return MessageBox( hWnd, lpText, lpCaption, uType );
}
return ExtraAllTheSame( hWnd, lpText, lpCaption, uType, 0, NULL, pbCheckRes, FUNCTION_NORMAL );
}
int EmaBoxEx( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType, WORD wLanguageId, int * pbCheckRes )
{
/* Check extra flags */
if( ( uType & MB_EXTRAMASC ) == 0 )
{
/* No extra */
return MessageBoxEx( hWnd, lpText, lpCaption, uType, wLanguageId );
}
return ExtraAllTheSame( hWnd, lpText, lpCaption, uType, wLanguageId, NULL, pbCheckRes, FUNCTION_EXTENDED );
}
int EmaBoxIndirect( const LPMSGBOXPARAMS lpMsgBoxParams, int * pbCheckRes )
{
/* Check extra flags */
if( ( lpMsgBoxParams->dwStyle & MB_EXTRAMASC ) == 0 )
{
/* No extra */
return MessageBoxIndirect( lpMsgBoxParams );
}
return ExtraAllTheSame( NULL, NULL, NULL, 0, 0, lpMsgBoxParams, pbCheckRes, FUNCTION_INDIRECT );
}
int EmaBoxLive()
{
dwTlsSlot = TlsAlloc();
if( dwTlsSlot == TLS_OUT_OF_INDEXES ) return 0;
return 1;
}
int EmaBoxDie()
{
if( dwTlsSlot == TLS_OUT_OF_INDEXES ) return 0;
TlsFree( dwTlsSlot );
return 1;
}
+141
View File
@@ -0,0 +1,141 @@
/*//////////////////////////////////////////////////////////////////////////////
// ExtraMessageBox
//
// Copyright © 2006 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
//////////////////////////////////////////////////////////////////////////////*/
#ifndef EXTRA_MESSAGE_BOX_H
#define EXTRA_MESSAGE_BOX_H 1
#include "EmaboxConfig.h"
#include <windows.h>
#include <tchar.h>
// =======================================================================================
// Global declarations
#include "../Global.h"
// =======================================================================================
/*
== TYPE =============================================================================
#define MB_TYPEMASK 15 1111
#define MB_OK 0 0000
#define MB_OKCANCEL 1 0001
#define MB_ABORTRETRYIGNORE 2 0010
#define MB_YESNOCANCEL 3 0011
#define MB_YESNO 4 0100
#define MB_RETRYCANCEL 5 0101
#define MB_CANCELTRYCONTINUE 6 0110
*/
#define MB_YESNOCANCELALL 7 /* 0111 */
#define MB_YESNOALL 8 /* 1000 */
/*
== ICON =============================================================================
#define MB_ICONMASK 240 11110000
#define MB_ICONERROR 16 00010000
#define MB_ICONHAND 16 00010000
#define MB_ICONSTOP 16 00010000
#define MB_ICONQUESTION 32 00100000
#define MB_ICONEXCLAMATION 0x30 00110000
#define MB_ICONWARNING 0x30 00110000
#define MB_ICONINFORMATION 64 01000000
#define MB_ICONASTERISK 64 01000000
#define MB_USERICON 128 10000000
== DEFAULT BUTTON ===================================================================
#define MB_DEFMASK 3840 111100000000
#define MB_DEFBUTTON1 0 000000000000
#define MB_DEFBUTTON2 256 000100000000
#define MB_DEFBUTTON3 512 001000000000
#define MB_DEFBUTTON4 0x300 001100000000
*/
#define MB_DEFBUTTON5 1024 /* 010000000000 */
#define MB_DEFBUTTON6 1280 /* 010100000000 */
/*
== MODE =============================================================================
#define MB_MODEMASK 0x00003000 11000000000000
#define MB_APPLMODAL 0 00000000000000
#define MB_SYSTEMMODAL 4096 01000000000000
#define MB_TASKMODAL 0x2000 10000000000000
== MISC =============================================================================
#define MB_MISCMASK 0x0000C000 1100000000000000
#define MB_HELP 0x4000 0100000000000000
#define MB_NOFOCUS 0x00008000 1000000000000000
== FLAGS ============================================================================
#define MB_SETFOREGROUND 0x10000 10000000000000000
#define MB_DEFAULT_DESKTOP_ONLY 0x20000 100000000000000000
#define MB_TOPMOST 0x40000 1000000000000000000
#define MB_SERVICE_NOTIFICATION_NT3X 0x00040000 1000000000000000000
#define MB_SERVICE_NOTIFICATION 0x00040000 1000000000000000000
#define MB_TOPMOST 0x40000 1000000000000000000
#define MB_RIGHT 0x80000 10000000000000000000
#define MB_RTLREADING 0x100000 100000000000000000000
#define MB_SERVICE_NOTIFICATION 0x00200000 1000000000000000000000
== EXTRA FLAGS ======================================================================
*/
#define MB_EXTRAMASC 0xF0000000 /* 11110000000000000000000000000000 */
#define MB_CHECKMASC 0xC0000000 /* 11000000000000000000000000000000 */
#define MB_CHECKNONE 0 /* 00000000000000000000000000000000 */
#define MB_CHECKNEVERAGAIN 0x40000000 /* 01000000000000000000000000000000 */
#define MB_CHECKREMEMBERCHOICE 0x80000000 /* 10000000000000000000000000000000 */
#define MB_CLOSEMASK 0x30000000 /* 00110000000000000000000000000000 */
#define MB_NORMALCLOSE 0 /* 00000000000000000000000000000000 */
#define MB_DISABLECLOSE 0x10000000 /* 00010000000000000000000000000000 */
#define MB_NOCLOSE 0x20000000 /* 00100000000000000000000000000000 */
/* Function aliases */
#define ExtraMessageBoxLive EmaBoxLive
#define ExtraMessageBoxDie EmaBoxDie
#define ExtraMessageBox EmaBox
#define ExtraMessageBoxEx EmaBoxEx
#define ExtraMessageBoxIndirect EmaBoxIndirect
int EmaBoxLive();
int EmaBoxDie();
int EmaBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType,
int * pbCheckRes
);
int EmaBoxEx(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType,
WORD wLanguageId,
int * pbCheckRes
);
int EmaBoxIndirect(
const LPMSGBOXPARAMS lpMsgBoxParams,
int * pbCheckRes
);
#endif /* EXTRA_MESSAGE_BOX_H */
+32
View File
@@ -0,0 +1,32 @@
/*//////////////////////////////////////////////////////////////////////////////
// ExtraMessageBox
//
// Copyright © 2006 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
//////////////////////////////////////////////////////////////////////////////*/
#ifndef EXTRA_MESSAGE_BOX_CONFIG_H
#define EXTRA_MESSAGE_BOX_CONFIG_H 1
/* Allow laziness */
#define EMA_AUTOINIT
/* Allow overwriting message text */
#ifndef EMA_TEXT_NEVER_AGAIN
# define EMA_TEXT_NEVER_AGAIN szNeverAgain
#endif
#ifndef EMA_TEXT_REMEMBER_CHOICE
# define EMA_TEXT_REMEMBER_CHOICE szRememberChoice
#endif
#endif /* EXTRA_MESSAGE_BOX_CONFIG_H */
+233
View File
@@ -0,0 +1,233 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Embed.h"
#include "Console.h"
#define CLASSNAME_EMBED TEXT( "Winamp Gen" )
#define TITLE_EMBED TEXT( "Embed target" )
#define EMBED_WIDTH 320
#define EMBED_HEIGHT 240
const TCHAR * const szEmbedTitle = TITLE_EMBED;
bool bEmbedClassRegistered = false;
LRESULT CALLBACK WndprocEmbed( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
////////////////////////////////////////////////////////////////////////////////
/// Creates a new embed window.
///
/// @param ews Embed window state
/// @return New embed window handle
////////////////////////////////////////////////////////////////////////////////
HWND Embed::Embed( embedWindowState * ews )
{
// Register class
if ( !bEmbedClassRegistered )
{
WNDCLASS wc = {
0, // UINT style
WndprocEmbed, // WNDPROC lpfnWndProc
0, // int cbClsExtra
0, // int cbWndExtra
g_hInstance, // HINSTANCE hInstance
NULL, // HICON hIcon
LoadCursor( NULL, IDC_ARROW ), // HCURSOR hCursor
( HBRUSH )COLOR_WINDOW, // HBRUSH hbrBackground
NULL, // LPCTSTR lpszMenuName
CLASSNAME_EMBED // LPCTSTR lpszClassName
};
if( !RegisterClass( &wc ) ) return NULL;
bEmbedClassRegistered = true;
}
// Create window
HWND WindowEmbed = CreateWindowEx(
WS_EX_WINDOWEDGE | // DWORD dwExStyle
WS_EX_TOOLWINDOW, //
CLASSNAME_EMBED, // LPCTSTR lpClassName
szEmbedTitle, // LPCTSTR lpWindowName
WS_OVERLAPPED | // DWORD dwStyle
WS_CLIPCHILDREN | //
WS_BORDER | //
WS_CAPTION | //
WS_SYSMENU | //
WS_THICKFRAME | //
WS_MINIMIZEBOX | //
WS_MAXIMIZEBOX, //
10, // int x
10, // int y
EMBED_WIDTH, // int nWidth
EMBED_HEIGHT, // int nHeight
NULL, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
Console::Append( TEXT( "Embed window born" ) );
Console::Append( TEXT( " " ) );
if( !ews || !ews->me ) return WindowEmbed;
SetParent( ews->me, WindowEmbed );
return WindowEmbed;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
inline bool SameThread( HWND hOther )
{
const DWORD dwOtherThreadId = GetWindowThreadProcessId( hOther, NULL );
const DWORD dwThisThreadId = GetCurrentThreadId();
return ( dwOtherThreadId == dwThisThreadId );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndprocEmbed( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
// static bool bAllowSizeMove = false;
switch( message )
{
case WM_PARENTNOTIFY:
switch( LOWORD( wp ) )
{
case WM_DESTROY:
{
const HWND hChild = GetWindow( hwnd, GW_CHILD );
if( !SameThread( hChild ) )
{
// Vis plugin
DestroyWindow( hwnd );
}
break;
}
}
break;
case WM_SIZE:
{
const HWND hChild = GetWindow( hwnd, GW_CHILD );
if( !hChild ) break;
MoveWindow( hChild, 0, 0, LOWORD( lp ), HIWORD( lp ), TRUE );
break;
}
/*
case WM_ENTERSIZEMOVE:
bAllowSizeMove = true;
break;
case WM_EXITSIZEMOVE:
bAllowSizeMove = false;
break;
case WM_WINDOWPOSCHANGING:
{
WINDOWPOS * pos = ( WINDOWPOS * )lp;
// Update child
if( IsWindow( WindowEmbedChild = GetWindow( WindowEmbed, GW_CHILD ) ) )
{
RECT r;
GetClientRect( WindowEmbed, &r );
MoveWindow( WindowEmbedChild, 0, 0, r.right, r.bottom, TRUE );
}
if( !bAllowSizeMove )
{
// Force SWP_NOMOVE
if( ( pos->flags & SWP_NOMOVE ) == 0 )
{
pos->flags |= SWP_NOMOVE;
}
// Force SWP_NOSIZE
if( ( pos->flags & SWP_NOSIZE ) == 0 )
{
pos->flags |= SWP_NOSIZE;
}
return 0;
}
break;
}
*/
case WM_SHOWWINDOW:
{
const HWND hChild = GetWindow( hwnd, GW_CHILD );
if( wp ) // Shown
{
// Update child size
RECT r;
GetClientRect( hwnd, &r );
MoveWindow( hChild, 0, 0, r.right, r.bottom, TRUE );
}
else // Hidden
{
ShowWindow( hChild, SW_HIDE );
DestroyWindow( hChild );
}
break;
}
case WM_SYSCOMMAND:
if( ( wp & 0xFFF0 ) == SC_CLOSE )
{
const HWND hChild = GetWindow( hwnd, GW_CHILD );
if( SameThread( hChild ) )
{
// Not a vis plugin
ShowWindow( hwnd, SW_HIDE );
return 0;
}
}
break;
case WM_DESTROY:
{
const HWND hChild = GetWindow( hwnd, GW_CHILD );
if( hChild && SameThread( hChild ) )
{
DestroyWindow( hChild );
}
Console::Append( TEXT( "Embed window dead" ) );
Console::Append( TEXT( " " ) );
break;
}
}
return DefWindowProc( hwnd, message, wp, lp );
}
+36
View File
@@ -0,0 +1,36 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_EMBED_H
#define PA_EMBED_H
#include "Global.h"
#include "Winamp/wa_ipc.h"
////////////////////////////////////////////////////////////////////////////////
/// Embed window service.
/// Winamp provides embed windows so plugins don't have to take care
/// of window skinning. A plugin let's Winamp create an embed window
/// and uses this new window as parent for its own window.
////////////////////////////////////////////////////////////////////////////////
namespace Embed
{
HWND Embed( embedWindowState * ews );
};
#endif // PA_EMBED_H
+83
View File
@@ -0,0 +1,83 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Font.h"
HFONT hFont = NULL;
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Font::Create()
{
hFont = CreateFont(
-11, // int nHeight
0, // int nWidth
0, // int nEscapement
0, // int nOrientation
FW_REGULAR, // int fnWeight
FALSE, // DWORD fdwItalic
FALSE, // DWORD fdwUnderline
FALSE, // DWORD fdwStrikeOut
ANSI_CHARSET, // DWORD fdwCharSet
OUT_TT_PRECIS, // DWORD fdwOutputPrecision
CLIP_DEFAULT_PRECIS, // DWORD fdwClipPrecision
ANTIALIASED_QUALITY, // DWORD fdwQuality
FF_DONTCARE | DEFAULT_PITCH, // DWORD fdwPitchAndFamily
TEXT( "Verdana" ) // LPCTSTR lpszFace
);
return ( hFont != NULL );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Font::Destroy()
{
if( !hFont ) return false;
DeleteObject( hFont );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Font::Apply( HWND hwnd )
{
if( !hFont ) return false;
SendMessage(
hwnd,
WM_SETFONT,
( WPARAM )hFont,
FALSE
);
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
HFONT Font::Get()
{
return hFont;
}
+34
View File
@@ -0,0 +1,34 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_FONT_H
#define PA_FONT_H
#include "Global.h"
namespace Font
{
bool Create();
bool Destroy();
bool Apply( HWND hwnd );
HFONT Get();
};
#endif // PA_FONT_H
+199
View File
@@ -0,0 +1,199 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "GenPlugin.h"
#include "Main.h"
#include "Unicode.h"
#include "Console.h"
#include <string.h>
vector <GenPlugin *> gen_plugins; // extern
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
GenPlugin::GenPlugin( TCHAR * szDllpath, bool bKeepLoaded ) : Plugin( szDllpath )
{
iHookerIndex = -1;
plugin = NULL;
if( !Load() )
{
return;
}
gen_plugins.push_back( this );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool GenPlugin::Load()
{
if( IsLoaded() ) return true;
// (1) Load DLL
hDLL = LoadLibrary( GetFullpath() );
if( !hDLL ) return false;
// (2) Find export
WINAMP_GEN_GETTER winampGetGeneralPurposePlugin =
( WINAMP_GEN_GETTER )GetProcAddress( hDLL, "winampGetGeneralPurposePlugin" );
if( winampGetGeneralPurposePlugin == NULL )
{
FreeLibrary( hDLL );
hDLL = NULL;
return false;
}
// (3) Get module
plugin = winampGetGeneralPurposePlugin();
if( !plugin )
{
FreeLibrary( hDLL );
hDLL = NULL;
return false;
}
// (4) Process module
plugin->hDllInstance = hDLL;
plugin->hwndParent = WindowMain;
// Note: Some plugins (mainly old ones) set description in init.
// Therefore we init first and copy the name after.
// (5) Init
if( plugin->init )
{
const WNDPROC WndprocBefore = ( WNDPROC )GetWindowLong( WindowMain, GWL_WNDPROC );
plugin->init();
const WNDPROC WndprocAfter = ( WNDPROC )GetWindowLong( WindowMain, GWL_WNDPROC );
if( WndprocBefore != WndprocAfter )
{
WndprocBackup = WndprocBefore;
iHookerIndex = iWndprocHookCounter++;
}
}
if( !szName )
{
// Note: The prefix is not removed to hide their
// origin at Nullsoft! It just reads easier.
if( !strnicmp( plugin->description, "nullsoft ", 9 ) )
{
plugin->description += 9;
}
// Get rid of " (xxx.dll)" postfix
char * walk = plugin->description + strlen( plugin->description ) - 5;
while( true )
{
if( ( walk <= plugin->description ) || strnicmp( walk, ".dll)", 5 ) ) break;
while( ( walk > plugin->description ) && ( *walk != '(' ) ) walk--;
if( walk <= plugin->description ) break;
walk--;
if( ( walk <= plugin->description ) || ( *walk != ' ' ) ) break;
*walk = '\0';
}
iNameLen = ( int )strlen( plugin->description );
szName = new TCHAR[ iNameLen + 1 ];
ToTchar( szName, plugin->description, iNameLen );
szName[ iNameLen ] = TEXT( '\0' );
}
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Loading <%s>, %s" ), GetFilename(), szName );
Console::Append( szBuffer );
Console::Append( TEXT( " " ) );
// Note: Plugins that use a wndproc hook need
// to be unloaded in the inverse loading order.
// This is due to the nature of wndproc hooking.
if( iHookerIndex != -1 )
{
Console::Append( TEXT( "Wndproc hook added (by plugin)" ) );
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool GenPlugin::Unload()
{
if( !IsLoaded() ) return true;
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Unloading <%s>" ), GetFilename() );
Console::Append( szBuffer );
Console::Append( TEXT( " " ) );
printf( ">>>Unloading <%s>\n" , GetFilename() );
// Quit
if( plugin )
{
if( plugin->quit ) plugin->quit();
plugin = NULL;
}
// Remove wndproc hook
if( ( iHookerIndex != -1 ) && ( iHookerIndex == iWndprocHookCounter - 1 ) )
{
// If we don't restore it the plugins wndproc will
// still be called which is not there anymore -> crash
SetWindowLong( WindowMain, GWL_WNDPROC, ( LONG )WndprocBackup );
Console::Append( TEXT( "Wndproc hook removed (by host)" ) );
Console::Append( TEXT( " " ) );
iHookerIndex = -1;
iWndprocHookCounter--;
}
FreeLibrary( hDLL );
hDLL = NULL;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool GenPlugin::Config()
{
if( !IsLoaded() ) return false;
if( !plugin ) return false;
if( !plugin->config ) return false;
plugin->config();
return true;
}
+64
View File
@@ -0,0 +1,64 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_GEN_PLUGIN_H
#define PA_GEN_PLUGIN_H
#include "Global.h"
#include "Plugin.h"
#include "Winamp/Gen.h"
#include <vector>
using namespace std;
typedef winampGeneralPurposePlugin * ( * WINAMP_GEN_GETTER )( void );
class GenPlugin;
extern vector <GenPlugin *> gen_plugins;
////////////////////////////////////////////////////////////////////////////////
/// Winamp general purpose plugin wrapper
////////////////////////////////////////////////////////////////////////////////
class GenPlugin : public Plugin
{
public:
GenPlugin( TCHAR * szDllpath, bool bKeepLoaded );
bool Load();
bool Unload();
TCHAR * GetTypeString() { return TEXT( "General" ); }
int GetTypeStringLen() { return 7; }
PluginType GetType() { return PLUGIN_TYPE_GEN; }
inline bool IsActive() { return IsLoaded(); }
bool Config();
inline bool AllowRuntimeUnload() { return ( iHookerIndex == -1 ) || ( iHookerIndex == iWndprocHookCounter - 1 ); }
private:
winampGeneralPurposePlugin * plugin;
};
#endif // PA_GEN_PLUGIN_H
+151
View File
@@ -0,0 +1,151 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Settings
// ¯¯¯¯¯¯¯¯¯¯
/* This will build Plainamp without the GUI. Todo: Fix this, I disabled a little to much
to make the regular GUI version build */
#define NOGUI
////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯
#include "../../../../Source/Core/Common/Src/ConsoleWindow.h" // Global common
/////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Declarations and definitions
// ¯¯¯¯¯¯¯¯¯¯
// =======================================================================================
// Because there are undefined in 64 bit it's easy to redefine them in case we use 64 bit
// ---------------------
#ifdef _M_X64
#define GWL_WNDPROC (-4)
#define GetWindowLong GetWindowLongPtrA // or GetWindowLongPtr
#endif
// =======================================================================================
////////////////////////////////////
// =======================================================================================
// Back to Plainamp code
// ---------------------
#ifndef PA_GLOBAL_H
#define PA_GLOBAL_H
// #include "ide_devcpp/Plainamp_Private.h"
#ifdef UNICODE
# define PA_UNICODE
#else
# ifdef _UNICODE
# define PA_UNICODE
# endif
#endif
// For GetLongPathName
#if _WIN32_WINDOWS < 0x0410
# undef _WIN32_WINDOWS
# define _WIN32_WINDOWS 0x0410
#endif
#define WIN32_LEAN_AND_MEAN
/*
#ifndef WINVER
# define WINVER 0x0500
#else
# if (WINVER < 0x0500)
# undef WINVER
# define WINVER 0x0500
# endif
#endif
*/
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#ifndef _WIN32_IE
# define _WIN32_IE 0x0400
#else
# if (_WIN32_IE < 0x0400)
# undef _WIN32_IE
# define _WIN32_IE 0x0400
# endif
#endif
#include <commctrl.h>
extern HINSTANCE g_hInstance;
extern TCHAR * szHomeDir;
extern int iHomeDirLen;
extern TCHAR * szPluginDir;
extern int iPluginDirLen;
/*
inline int abs( int x )
{
return ( x < 0 ) ? -x : x;
}
*/
inline int MIN( int a, int b )
{
return ( a < b ) ? a : b;
}
inline int MAX( int a, int b )
{
return ( a > b ) ? a : b;
}
// Typo help
#define UNIT UINT
#define UINT_PRT UINT_PTR
struct TextCompare
{
bool operator()( const TCHAR * a, const TCHAR * b ) const
{
return _tcscmp( a, b ) < 0;
}
};
#endif // PA_GLOBAL_H
+28
View File
@@ -0,0 +1,28 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_GLOBAL_VERSION_H
#define PA_GLOBAL_VERSION_H
#define FILE_DESCRIPTION "Plainamp"
#define VER_STRING "0.2.3.1"
#define PLAINAMP_TITLE TEXT( FILE_DESCRIPTION )
#define PLAINAMP_VERSION TEXT( VER_STRING )
#define PLAINAMP_LONG_TITLE PLAINAMP_TITLE TEXT( " " ) PLAINAMP_VERSION
#endif // PA_GLOBAL_VERSION_H
+483
View File
@@ -0,0 +1,483 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Input.h"
#include "Console.h"
#include "Status.h"
#include "Playback.h"
#include "InputPlugin.h"
#include "VisPlugin.h"
#include "DspPlugin.h"
#include "VisCache.h"
#include "Output.h"
/*
#define FIXED_POINT 16
#include "kiss_fft/kiss_fftr.h"
*/
// =======================================================================================
//#include "fftw3/fftw3.h"
// =======================================================================================
#include <math.h>
// #define SKIPPY
#ifndef SKIPPY
# define MAX_DATA_FPS ( 1000 / 12 ) // in_mp3 gives new vis data every 13 ms, so 12 leaves a little space
#else
# define MAX_DATA_FPS ( 1000 / 24 ) // will skip every second frame
#endif
#ifdef SKIPPY
bool bLastSkipped = true;
#endif
int iSpecChannels = 2;
int iWaveChannels = 2;
/*
kiss_fft_cfg kiss = { 0 };
bool bKissInitDone = false;
*/
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int dsp_isactive()
{
////////////////////////////////////////////////////////////////////////////////
DspLock.Enter();
////////////////////////////////////////////////////////////////////////////////
int res = ( active_dsp_count > 0 );
////////////////////////////////////////////////////////////////////////////////
DspLock.Leave();
////////////////////////////////////////////////////////////////////////////////
return res;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int dsp_dosamples( short int * samples, int numsamples, int bps, int nch, int srate )
{
int num = numsamples;
////////////////////////////////////////////////////////////////////////////////
DspLock.Enter();
////////////////////////////////////////////////////////////////////////////////
for( int i = 0; i < active_dsp_count; i++ )
{
// Process
num = active_dsp_mods[ i ]->mod->ModifySamples(
active_dsp_mods[ i ]->mod,
samples,
numsamples,
bps,
nch,
srate
);
}
////////////////////////////////////////////////////////////////////////////////
DspLock.Leave();
////////////////////////////////////////////////////////////////////////////////
return num;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void SAVSAInit( int maxlatency_in_ms, int srate )
{
////////////////////////////////////////////////////////////////////////////////
VisCache::Create();
VisCache::EnsureLatency( maxlatency_in_ms );
VisCache::EnsureDataFps( MAX_DATA_FPS );
VisCache::Clean();
////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void SAVSADeInit()
{
// TODO
// Console::Append( TEXT( "SAVSADeInit" ) );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void SAAddPCMData( void * PCMData, int nch, int bps, int timestamp )
{
// TODO
// Console::Append( TEXT( "SAAddPCMData" ) );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int SAGetMode()
{
// TODO
// Console::Append( TEXT( "SAGetMode" ) );
return 0;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void SAAdd( void * data, int timestamp, int csa )
{
// TODO
// Console::Append( TEXT( "SAAdd" ) );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VSAAddPCMData( void * PCMData, int nch, int bps, int timestamp )
{
// TODO
// Console::Append( TEXT( "VSAAddPCMData" ) );
#ifdef SKIPPY
if( bLastSkipped )
bLastSkipped = false;
else
{
// Skip
bLastSkipped = true;
return;
}
#endif
////////////////////////////////////////////////////////////////////////////////
bool bVisLockLeft = false;
VisLock.Enter();
////////////////////////////////////////////////////////////////////////////////
if( active_vis_count )
{
////////////////////////////////////////////////////////////////////////////////
VisLock.Leave();
bVisLockLeft = true;
////////////////////////////////////////////////////////////////////////////////
VisCache::NextFrame();
VisCache::SetWriteTime( timestamp );
VisCache::SetReadTime( active_input_plugin->plugin->GetOutputTime() );
short * source = ( short * )PCMData;
// Waveform
static unsigned char wave_left[ 576 ];
static unsigned char wave_right[ 576 ];
if( nch < 2 )
{
// Mono
for( int i = 0; i < 576; i++ )
{
wave_left[ i ] = ( source[ i ] >> 8 );
}
VisCache::PutWaveLeft( wave_left );
}
else
{
int i;
// Stereo or more
for( i = 0; i < 576; i++ )
{
wave_left [ i ] = ( source[ i * nch ] >> 8 );
wave_right[ i ] = ( source[ i * nch + 1 ] >> 8 );
}
VisCache::PutWaveLeft( wave_left );
VisCache::PutWaveRight( wave_right );
}
// TODO: Much to optimize!
// =======================================================================================
/*
// Spectrum
static unsigned char spec_left[ 576 ];
static unsigned char spec_right[ 576 ];
static fftw_complex * in = NULL;
static fftw_complex * out = NULL;
if( !in )
{
in = ( fftw_complex * )fftw_malloc( 576 * sizeof( fftw_complex ) );
out = ( fftw_complex * )fftw_malloc( 576 * sizeof( fftw_complex ) );
}
static const double factor = 1.0 / 65536.0 / sqrt( 2.0 );
// Put left
int index = 0;
for( int i = 0; i < 576; i++ )
{
in[ i ][ 0 ] = source[ index += nch ];
in[ i ][ 1 ] = 0.0;
}
// Init FFT
fftw_plan p = fftw_plan_dft_1d( 576, in, out, FFTW_FORWARD, FFTW_ESTIMATE );
// Run left
fftw_execute( p );
// Get left
for( int i = 0; i < 576; i++ )
{
if( i & 1 )
{
spec_left [ i ] = spec_left [ i - 1 ];
continue;
}
const double re = out[ i >> 1 ][ 0 ];
const double im = out[ i >> 1 ][ 1 ];
const double root = sqrt( re*re + im*im );
const double final = 160.0 * log10( 1.0 + root * factor );
spec_left[ i ] = ( final < 255.0 ) ? ( unsigned char )final : 255;
}
VisCache::PutSpecLeft( spec_left );
if( nch > 1 )
{
// Put right
index = 1;
for( int i = 0; i < 576; i++ )
{
in[ i ][ 0 ] = source[ index += nch ];
}
// Run right
fftw_execute( p );
// Get right
for( int i = 0; i < 576; i++ )
{
if( i & 1 )
{
spec_right[ i ] = spec_right[ i - 1 ];
continue;
}
const double re = out[ i >> 1 ][ 0 ];
const double im = out[ i >> 1 ][ 1 ];
const double root = sqrt( re*re + im*im );
const double final = 160.0 * log10( 1.0 + root * factor );
spec_right[ i ] = ( final < 255.0 ) ? ( unsigned char )final : 255;
}
VisCache::PutSpecRight( spec_right );
}
// =======================================================================================
*/
// Cleanup FFT
// =======================================================================================
//fftw_destroy_plan( p );
// =======================================================================================
// fftw_free(in);
// fftw_free(out);
}
////////////////////////////////////////////////////////////////////////////////
if( bVisLockLeft ) VisLock.Enter();
////////////////////////////////////////////////////////////////////////////////
for( int i = 0; i < active_vis_count; i++ )
{
active_vis_mods[ i ]->bAllowRender = true;
}
////////////////////////////////////////////////////////////////////////////////
VisLock.Leave();
////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int VSAGetMode( int * specNch, int * waveNch )
{
iSpecChannels = 0;
iWaveChannels = 0;
////////////////////////////////////////////////////////////////////////////////
VisLock.Enter();
////////////////////////////////////////////////////////////////////////////////
for( int i = 0; i < active_vis_count; i++ )
{
const int iSpec = active_vis_mods[ i ]->mod->spectrumNch;
const int iWave = active_vis_mods[ i ]->mod->waveformNch;
if( iSpec > iSpecChannels ) iSpecChannels = iSpec;
if( iWave > iWaveChannels ) iWaveChannels = iWave;
}
////////////////////////////////////////////////////////////////////////////////
VisLock.Leave();
////////////////////////////////////////////////////////////////////////////////
*specNch = iSpecChannels;
*waveNch = iWaveChannels;
return 1;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VSAAdd( void * data, int timestamp )
{
#ifdef SKIPPY
if( bLastSkipped )
bLastSkipped = false;
else
{
// Skip
bLastSkipped = true;
return;
}
#endif
////////////////////////////////////////////////////////////////////////////////
bool bVisLockLeft = false;
VisLock.Enter();
////////////////////////////////////////////////////////////////////////////////
if( active_vis_count )
{
////////////////////////////////////////////////////////////////////////////////
VisLock.Leave();
bVisLockLeft = true;
////////////////////////////////////////////////////////////////////////////////
VisCache::NextFrame();
VisCache::SetWriteTime( timestamp );
VisCache::SetReadTime( active_input_plugin->plugin->GetOutputTime() );
unsigned char * source = ( unsigned char * )data;
if( iSpecChannels > 0 )
{
VisCache::PutSpecLeft( source );
source += 576;
}
if( iSpecChannels > 1 )
{
VisCache::PutSpecRight( source );
source += 576;
}
if( iWaveChannels > 0 )
{
VisCache::PutWaveLeft( source );
source += 576;
}
if( iWaveChannels > 1 )
{
VisCache::PutWaveRight( source );
}
}
////////////////////////////////////////////////////////////////////////////////
if( bVisLockLeft ) VisLock.Enter();
////////////////////////////////////////////////////////////////////////////////
for( int i = 0; i < active_vis_count; i++ )
{
active_vis_mods[ i ]->bAllowRender = true;
}
////////////////////////////////////////////////////////////////////////////////
VisLock.Leave();
////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VSASetInfo( int nch, int srate )
{
// TODO
////////////////////////////////////////////////////////////////////////////////
VisCache::Create();
VisCache::EnsureDataFps( MAX_DATA_FPS );
VisCache::Clean();
////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void SetInfo( int bitrate, int srate, int stereo, int synched )
{
// TODO
static int last_valid_srate = 0;
if( bitrate < 0 ) return;
if( srate < 0 )
srate = last_valid_srate;
else
last_valid_srate = srate;
TCHAR szBuffer[ 5000 ] = TEXT( "" );
_stprintf( szBuffer, TEXT( " %i kbps, %i kHz" ), bitrate, srate );
StatusUpdate( szBuffer );
}
+28
View File
@@ -0,0 +1,28 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Global.h"
int dsp_isactive();
int dsp_dosamples( short int * samples, int numsamples, int bps, int nch, int srate );
void SAVSAInit( int maxlatency_in_ms, int srate );
void SAVSADeInit();
void SAAddPCMData( void * PCMData, int nch, int bps, int timestamp );
int SAGetMode();
void SAAdd(void * data, int timestamp, int csa );
void VSAAddPCMData( void * PCMData, int nch, int bps, int timestamp );
int VSAGetMode( int * specNch, int * waveNch );
void VSAAdd( void * data, int timestamp );
void VSASetInfo( int nch, int srate );
void SetInfo( int bitrate, int srate, int stereo, int synched );
+389
View File
@@ -0,0 +1,389 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
// =======================================================================================
#include "Global.h"
// =======================================================================================
#include "InputPlugin.h"
#include "Console.h"
#include "Main.h"
#include "Input.h"
#include "Unicode.h"
map <TCHAR *, InputPlugin *, TextCompare> ext_map; // extern
vector <InputPlugin *> input_plugins; // extern
InputPlugin * active_input_plugin = NULL; // extern
// =======================================================================================
// The InputPlugin class is inherited from the Plugin class
InputPlugin::InputPlugin( TCHAR * szDllpath, bool bKeepLoaded ) : Plugin( szDllpath )
{
iHookerIndex = -1;
szFilters = NULL;
iFiltersLen = 0;
plugin = NULL;
//Console::Print("\InputPlugin::InputPlugin > Begin\n");
if( !Load() )
{
return;
}
if( !bKeepLoaded )
{
Unload();
}
input_plugins.push_back( this );
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
InputPlugin::~InputPlugin()
{
if( szFilters ) delete [] szFilters;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
bool InputPlugin::Load()
{
printf("InputPlugin::Load() was called. IsLoaded: %i\n", IsLoaded());
if( IsLoaded() ) return true;
// (1) Load DLL
hDLL = LoadLibrary( GetFullpath() );
if( !hDLL ) return false;
// (2) Find export
WINAMP_INPUT_GETTER winampGetInModule2 =
( WINAMP_INPUT_GETTER )GetProcAddress( hDLL, "winampGetInModule2" );
if( winampGetInModule2 == NULL )
{
FreeLibrary( hDLL );
hDLL = NULL;
return false;
}
// (3) Get module
plugin = winampGetInModule2();
if( plugin == NULL )
{
FreeLibrary( hDLL );
hDLL = NULL;
return false;
}
// (4) Process module
plugin->hDllInstance = hDLL;
plugin->hMainWindow = WindowMain;
plugin->SAVSAInit = SAVSAInit;
plugin->SAVSADeInit = SAVSADeInit;
plugin->SAAddPCMData = SAAddPCMData;
plugin->SAGetMode = SAGetMode;
plugin->SAAdd = SAAdd;
plugin->VSAAddPCMData = VSAAddPCMData;
plugin->VSAGetMode = VSAGetMode;
plugin->VSAAdd = VSAAdd;
plugin->VSASetInfo = VSASetInfo;
plugin->dsp_dosamples = dsp_dosamples;
plugin->dsp_isactive = dsp_isactive;
plugin->SetInfo = SetInfo;
if( !szName )
{
// Note: The prefix is not removed to hide their
// origin at Nullsoft! It just reads easier.
if( !strnicmp( plugin->description, "nullsoft ", 9 ) )
{
plugin->description += 9;
if( !strnicmp( plugin->description, "mpeg(layer1-3/ct aac+/dolby aac) ", 33 ) )
{
plugin->description += ( 33 - 5 );
memcpy( plugin->description, "MPEG", 4 * sizeof( char ) );
}
}
iNameLen = ( int )strlen( plugin->description );
szName = new TCHAR[ iNameLen + 1 ];
ToTchar( szName, plugin->description, iNameLen );
szName[ iNameLen ] = TEXT( '\0' );
}
// (5) Init
const WNDPROC WndprocBefore = ( WNDPROC )GetWindowLong( WindowMain, GWL_WNDPROC );
plugin->Init();
const WNDPROC WndprocAfter = ( WNDPROC )GetWindowLong( WindowMain, GWL_WNDPROC );
if( WndprocBefore != WndprocAfter )
{
WndprocBackup = WndprocBefore;
iHookerIndex = iWndprocHookCounter++;
}
#ifdef NOGUI
printf( "Loading <%s>, %s\n" , GetFilename(), szName );
#else
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Loading <%s>, %s" ), GetFilename(), szName );
Console::Append( szBuffer );
#endif
Integrate(); // This function is just below
// Note: Plugins that use a wndproc hook need
// to be unloaded in the inverse loading order.
// This is due to the nature of wndproc hooking.
if( iHookerIndex != -1 )
{
Console::Append( TEXT( "Wndproc hook added (by plugin)" ) );
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
bool InputPlugin::Integrate()
{
if( !IsLoaded() ) return false;
// (6) Build filter
// (6a) First pass: get needed buffer length
int needed = 0;
int len = 0;
bool even = false;
char * walk = plugin->FileExtensions;
while( ( len = ( int )strlen( walk ) ) > 0 )
{
len++; // For '\0'
if( even )
{
// Extensions e.g. "mp3;mp2;mp1"
// Worst case "a;b;c" (5) --> "*.a;*.b;*.c" (11)
needed += ( 3 * len );
}
else
{
// Filter name e.g. "MPEG audio files"
needed += len;
}
even = !even;
walk += len;
}
szFilters = new TCHAR[ needed + 1 ];
TCHAR * walk_out = szFilters;
// (6b) Once again with copy
walk = plugin->FileExtensions;
even = false;
while( true )
{
// Check extensions
char * start_filter = walk;
const int len_filter = ( int )strlen( walk );
if( len_filter == 0 )
{
// End reached
break;
}
walk += len_filter + 1;
// Check filter name
char * start_display = walk;
int len_display = ( int )strlen( walk );
if( len_display == 0 )
{
break;
}
walk += ++len_display;
// Append filter name
ToTchar( walk_out, start_display, len_display );
// =======================================================================================
// Print used filetypes
TCHAR szBuffer[ 5000 ];
*(walk_out + len_display) = TEXT( '\0' );
_stprintf( szBuffer, TEXT( " %s" ), walk_out );
Console::Append( szBuffer );
//printf( szBuffer, TEXT( " %s\n" ), walk_out );
// =======================================================================================
walk_out += len_display;
// Convert and append extensions
char * walk_filter = start_filter;
char * last_filter = start_filter;
int len;
while( true )
{
if( ( *walk_filter == ';' ) || ( *walk_filter == '\0' ) )
{
len = ( walk_filter - last_filter );
if( len < 1 )
{
break;
}
// Add extension to map
TCHAR * szExt = new TCHAR[ len + 1 ];
ToTchar( szExt, last_filter, len );
szExt[ len ] = TEXT( '\0' );
_tcslwr( szExt );
ext_map.insert( pair<TCHAR *, InputPlugin *>( szExt, this ) );
// Append extension as "*.ext[;\0]"
len++; // Also copy ';' and '\0'
memcpy( walk_out, TEXT( "*." ), 2 * sizeof( TCHAR ) );
walk_out += 2;
ToTchar( walk_out, last_filter, len );
walk_out += len;
// Any more extensions?
if( *walk_filter == '\0' )
{
break;
}
last_filter = walk_filter + 1;
}
walk_filter++;
}
if( *walk == '\0' )
{
*walk_out = TEXT( '\0' );
iFiltersLen = walk_out - szFilters;
break;
}
}
Console::Append( TEXT( " " ) );
return true;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
bool InputPlugin::DisIntegrate()
{
return true;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
bool InputPlugin::Unload()
{
if( !IsLoaded() ) return true;
DisIntegrate();
#ifndef NOGUI
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Unloading '%s'" ), GetFilename() );
Console::Append( szBuffer );
Console::Append( TEXT( " " ) );
#else
printf( ">>> Unloading '%s'\n" , GetFilename() );
#endif
// Quit
if( plugin )
{
if( plugin->Quit ) plugin->Quit();
plugin->outMod = NULL;
plugin = NULL;
}
// Remove wndproc hook
if( ( iHookerIndex != -1 ) && ( iHookerIndex == iWndprocHookCounter - 1 ) )
{
// If we don't restore it the plugins wndproc will
// still be called which is not there anymore -> crash
SetWindowLong( WindowMain, GWL_WNDPROC, ( LONG )WndprocBackup );
Console::Append( TEXT( "Wndproc hook removed (by host)" ) );
Console::Append( TEXT( " " ) );
iHookerIndex = -1;
iWndprocHookCounter--;
}
FreeLibrary( hDLL );
hDLL = NULL;
return true;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
bool InputPlugin::About( HWND hParent )
{
if( !plugin ) return false;
if( !plugin->About ) return false;
plugin->About( hParent );
return true;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
bool InputPlugin::Config( HWND hParent )
{
if( !plugin ) return false;
if( !plugin->Config ) return false;
plugin->Config( hParent );
// TODO: File extension could have changed (e.g. in_mp3)
// So we have to process ext_map here...
return true;
}
+96
View File
@@ -0,0 +1,96 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_INPUT_PLUGIN_H
#define PA_INPUT_PLUGIN_H
#include "Global.h"
#include "Plugin.h"
#include "Playback.h"
#include "Playlist.h"
#include "Winamp/In2.h"
#include <map>
#include <vector>
using namespace std;
typedef In_Module * ( * WINAMP_INPUT_GETTER )( void );
class InputPlugin;
extern map <TCHAR *, InputPlugin *, TextCompare> ext_map;
extern vector <InputPlugin *> input_plugins;
extern InputPlugin * active_input_plugin;
////////////////////////////////////////////////////////////////////////////////
/// Winamp input plugin wrapper
////////////////////////////////////////////////////////////////////////////////
class InputPlugin : public Plugin
{
public:
InputPlugin( TCHAR * szDllpath, bool bKeepLoaded );
~InputPlugin();
bool Load();
bool Unload();
TCHAR * GetTypeString() { return TEXT( "Input" ); }
int GetTypeStringLen() { return 5; }
PluginType GetType() { return PLUGIN_TYPE_INPUT; }
inline bool IsActive() { return false; }
bool About( HWND hParent );
bool Config( HWND hParent );
In_Module * plugin; // I moved this from private to public
private:
TCHAR * szFilters;
int iFiltersLen;
bool Integrate();
bool DisIntegrate();
// TODO
friend bool OpenPlay( TCHAR * szFilename, int iNumber );
friend bool Playback_PrevOrNext( bool bPrevOrNext );
friend bool Playback::Play();
friend bool Playback::Pause();
friend bool Playback::Stop();
friend bool Playback::UpdateSeek(); // this one calls some plugin-> members
friend int Playback::PercentToMs( float fPercent );
friend bool Playback::SeekPercent( float fPercent );
friend bool SeekRelative( int ms );
friend void Playback_Volume_Set( int iVol );
friend bool Playback::Pan::Set( int iPan );
friend void Playback_Eq_Set( int iPresetIndex );
friend void AddFiles();
friend void VSAAdd( void * data, int timestamp );
friend void VSAAddPCMData( void * PCMData, int nch, int bps, int timestamp );
friend int Playlist::GetTitle( int iIndex, char * szAnsiTitle, int iChars );
};
#endif // PA_INPUT_PLUGIN_H
+16
View File
@@ -0,0 +1,16 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
// #include "Lock.h"
// Code moved to <Lock.h> for inlining!
+111
View File
@@ -0,0 +1,111 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_LOCK_H
#define PA_LOCK_H
#include "Global.h"
// INFO: http://www.devarticles.com/c/a/Cplusplus/Multithreading-in-C/3/
// #define LOCK_USES_MUTEX
////////////////////////////////////////////////////////////////////////////////
/// Lock for thread synchronization
////////////////////////////////////////////////////////////////////////////////
class Lock
{
public:
Lock( TCHAR * szName );
~Lock();
void Enter();
void Leave();
private:
#ifndef LOCK_USES_MUTEX
CRITICAL_SECTION * m_pCrit;
#else
HANDLE hLock;
#endif
};
////////////////////////////////////////////////////////////////////////////////
/// Creates a new named lock.
/// Note: Don't use the same name for several locks
////////////////////////////////////////////////////////////////////////////////
inline Lock::Lock( TCHAR * szName )
{
#ifndef LOCK_USES_MUTEX
m_pCrit = new CRITICAL_SECTION;
InitializeCriticalSection( m_pCrit );
#else
hLock = CreateMutex( NULL, TRUE, szName );
ReleaseMutex( hLock );
#endif
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
inline Lock::~Lock()
{
#ifndef LOCK_USES_MUTEX
DeleteCriticalSection( m_pCrit );
delete [] m_pCrit;
#else
CloseHandle( hLock );
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// Closes lock.
////////////////////////////////////////////////////////////////////////////////
inline void Lock::Enter()
{
#ifndef LOCK_USES_MUTEX
EnterCriticalSection( m_pCrit );
#else
WaitForSingleObject( hLock, INFINITE );
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// Opens lock.
////////////////////////////////////////////////////////////////////////////////
inline void Lock::Leave()
{
#ifndef LOCK_USES_MUTEX
LeaveCriticalSection( m_pCrit );
#else
ReleaseMutex( hLock );
#endif
}
#endif // PA_LOCK_H
+816
View File
@@ -0,0 +1,816 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Documentation
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* ---- The Seekbar ----
Rebar.cpp handle the progress (playback position) bar. WndprocMain() is called every
second during playback. And several times a second when the cursor is moving over the
main window. If WM_TIMER called WndprocMain it calls Playback::UpdateSeek(); */
///////////////////////////////////
#include "Main.h"
#include "GlobalVersion.h"
#include "Playlist.h"
#include "Console.h"
#include "Status.h"
#include "Rebar.h"
#include "Playback.h"
#include "PluginManager.h"
#include "DspModule.h"
#include "VisModule.h"
#include "InputPlugin.h"
#include "OutputPlugin.h"
#include "InputPlugin.h"
#include "AddDirectory.h"
#include "AddFiles.h"
#include "Winamp.h"
#include "Winamp/wa_ipc.h"
#include "Config.h"
#include <shellapi.h>
#define CLASSNAME_MAIN TEXT( "Winamp v1.x" )
#define MAIN_TITLE PLAINAMP_LONG_TITLE
#define MAIN_WIDTH 731
#define MAIN_HEIGHT 562
HWND WindowMain = NULL; // extern
HMENU main_context_menu = NULL; // extern
HMENU play_context_menu = NULL;
HMENU opts_context_menu = NULL;
HMENU playback_context_menu = NULL;
LRESULT CALLBACK WndprocMain( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
WINDOWPLACEMENT WinPlaceMain;
void WinPlaceMainCallback( ConfVar * var )
{
if( !IsWindow( WindowMain ) ) return;
GetWindowPlacement( WindowMain, &WinPlaceMain );
}
const int cxScreen = GetSystemMetrics( SM_CXFULLSCREEN );
const int cyScreen = GetSystemMetrics( SM_CYFULLSCREEN );
RECT rMainDefault = {
( cxScreen - MAIN_WIDTH ) / 2,
( cyScreen - MAIN_HEIGHT ) / 2,
( cxScreen - MAIN_WIDTH ) / 2 + MAIN_WIDTH,
( cyScreen - MAIN_HEIGHT ) / 2 + MAIN_HEIGHT
};
ConfWinPlaceCallback cwpcWinPlaceMain(
&WinPlaceMain,
TEXT( "WinPlaceMain" ),
&rMainDefault,
WinPlaceMainCallback
);
bool bMinimizeToTray;
ConfBool cbMinimizeToTray( &bMinimizeToTray, TEXT( "MinimizeToTray" ), CONF_MODE_PUBLIC, true );
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool BuildMainWindow()
{
//#ifndef NOGUI
// =======================================================================================
/* Disabling this window creation cause continuous "Error setting DirectSound cooperative level"
messages for some reason. So I leave it here for now. */
// Register class
WNDCLASS wc = {
0, // UINT style
WndprocMain, // WNDPROC lpfnWndProc
0, // int cbClsExtra
0, // int cbWndExtra
g_hInstance, // HINSTANCE hInstance
LoadIcon( g_hInstance, TEXT( "IDI_ICON1" ) ), // HICON hIcon
LoadCursor( NULL, IDC_ARROW ), // HCURSOR hCursor
( HBRUSH )COLOR_WINDOW, // HBRUSH hbrBackground
NULL, // LPCTSTR lpszMenuName
CLASSNAME_MAIN // LPCTSTR lpszClassName
};
if( !RegisterClass( &wc ) ) return false;
// Create WindowMain
WindowMain = CreateWindowEx(
WS_EX_WINDOWEDGE, // DWORD dwExStyle
CLASSNAME_MAIN, // LPCTSTR lpClassName
MAIN_TITLE, // LPCTSTR lpWindowName
WS_OVERLAPPED | // DWORD dwStyle
// WS_VISIBLE | //
WS_CLIPCHILDREN | //
WS_BORDER | //
WS_SYSMENU | //
WS_THICKFRAME | //
WS_MINIMIZEBOX | //
WS_MAXIMIZEBOX, //
rMainDefault.left, // int x
rMainDefault.top, // int y
rMainDefault.right - rMainDefault.left, // int nWidth
rMainDefault.bottom - rMainDefault.top, // int nHeight
NULL, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
// =======================================================================================
//#endif
// =======================================================================================
#ifdef NOGUI
// If this is not called a crash occurs
PlaylistView::Create();
// We have now done what we wanted so we skip the rest of the file
return true;
#else
// =======================================================================================
if( !WindowMain )
{
UnregisterClass( CLASSNAME_MAIN, g_hInstance );
return false;
}
// Build context menu
HMENU main_menu = CreateMenu();
HMENU plainamp_menu = CreatePopupMenu();
HMENU playback_menu = CreatePopupMenu();
HMENU playlist_menu = CreatePopupMenu();
HMENU windows_menu = CreatePopupMenu();
// Plainamp
AppendMenu( plainamp_menu, MF_STRING, WINAMP_OPTIONS_PREFS, TEXT( "Preferences \tCtrl+P" ) );
AppendMenu( plainamp_menu, MF_SEPARATOR | MF_DISABLED | MF_GRAYED, ( UINT_PTR )-1, NULL );
AppendMenu( plainamp_menu, MF_STRING, WINAMP_HELP_ABOUT, TEXT( "&About\tCtrl+F1" ) );
AppendMenu( plainamp_menu, MF_STRING, WINAMP_FILE_QUIT, TEXT( "&Exit \tAlt+F4" ) );
// Playback
AppendMenu( playback_menu, MF_STRING, WINAMP_BUTTON1, TEXT( "Pre&vious \tZ" ) );
AppendMenu( playback_menu, MF_STRING, WINAMP_BUTTON2, TEXT( "&Play\tX" ) );
AppendMenu( playback_menu, MF_STRING, WINAMP_BUTTON3, TEXT( "P&ause\tC" ) );
AppendMenu( playback_menu, MF_STRING, WINAMP_BUTTON4, TEXT( "&Stop\tV" ) );
AppendMenu( playback_menu, MF_STRING, WINAMP_BUTTON5, TEXT( "&Next\tB" ) );
// Playlist
AppendMenu( playlist_menu, MF_STRING, ID_PE_OPEN, TEXT( "&Open\tCtrl+O" ) );
AppendMenu( playlist_menu, MF_STRING, ID_PE_SAVEAS, TEXT( "&Save as\tCtrl+S" ) );
AppendMenu( playlist_menu, MF_SEPARATOR | MF_DISABLED | MF_GRAYED, ( UINT_PTR )-1, NULL );
AppendMenu( playlist_menu, MF_STRING, WINAMP_FILE_PLAY, TEXT( "Add &files\tL" ) );
AppendMenu( playlist_menu, MF_STRING, WINAMP_FILE_DIR, TEXT( "Add &directory\tShift+L" ) );
AppendMenu( playlist_menu, MF_SEPARATOR | MF_DISABLED | MF_GRAYED, ( UINT_PTR )-1, NULL );
AppendMenu( playlist_menu, MF_STRING, PLAINAMP_PL_REM_SEL, TEXT( "Remove selected\tDel" ) );
AppendMenu( playlist_menu, MF_STRING, PLAINAMP_PL_REM_CROP, TEXT( "Remove unselected \tCtrl+Del" ) );
AppendMenu( playlist_menu, MF_STRING, ID_PE_CLEAR, TEXT( "Remove all\tCtrl+Shift+Del" ) );
AppendMenu( playlist_menu, MF_SEPARATOR | MF_DISABLED | MF_GRAYED, ( UINT_PTR )-1, NULL );
AppendMenu( playlist_menu, MF_STRING, ID_PE_SELECTALL, TEXT( "Select &all\tCtrl+A" ) );
AppendMenu( playlist_menu, MF_STRING, ID_PE_NONE, TEXT( "Select &zero\tCtrl+Shift+A" ) );
AppendMenu( playlist_menu, MF_STRING, ID_PE_INVERT, TEXT( "Select &invert\tCtrl+I" ) );
// Windows
AppendMenu( windows_menu, MF_STRING, MENU_MAIN_WINDOWS_CONSOLE, TEXT( "&Console" ) );
AppendMenu( windows_menu, MF_STRING, MENU_MAIN_WINDOWS_MANAGER, TEXT( "Plugin &Manager" ) );
// Main
AppendMenu( main_menu, MF_STRING | MF_POPUP, ( UINT_PTR )plainamp_menu, TEXT( "&Plainamp" ) );
AppendMenu( main_menu, MF_STRING | MF_POPUP, ( UINT_PTR )playback_menu, TEXT( "Play&back" ) );
AppendMenu( main_menu, MF_STRING | MF_POPUP, ( UINT_PTR )playlist_menu, TEXT( "Play&list" ) );
AppendMenu( main_menu, MF_STRING | MF_POPUP, ( UINT_PTR )windows_menu, TEXT( "&Windows" ) );
SetMenu( WindowMain, main_menu );
////////////////////////////////////////////////////////////////////////////////
main_context_menu = CreatePopupMenu();
AppendMenu( main_context_menu, MF_STRING, WINAMP_HELP_ABOUT, TEXT( "Plainamp" ) );
AppendMenu( main_context_menu, MF_SEPARATOR | MF_DISABLED | MF_GRAYED, ( UINT_PTR )-1, NULL );
play_context_menu = CreatePopupMenu();
AppendMenu( play_context_menu, MF_STRING, WINAMP_FILE_PLAY, TEXT( "Files \tL" ) );
AppendMenu( play_context_menu, MF_STRING, WINAMP_FILE_DIR, TEXT( "Folder \tShift+L" ) );
AppendMenu( main_context_menu, MF_STRING | MF_POPUP, ( UINT_PTR )play_context_menu, TEXT( "Play" ) );
AppendMenu( main_context_menu, MF_SEPARATOR | MF_DISABLED | MF_GRAYED, ( UINT_PTR )-1, NULL );
AppendMenu( main_context_menu, MF_STRING | MF_DISABLED | MF_GRAYED | MF_CHECKED, WINAMP_MAIN_WINDOW, TEXT( "Main Window\tAlt+W" ) );
AppendMenu( main_context_menu, MF_STRING | MF_DISABLED | MF_GRAYED | MF_CHECKED, WINAMP_OPTIONS_PLEDIT, TEXT( "Playlist Editor\tAlt+E" ) );
AppendMenu( main_context_menu, MF_STRING | MF_DISABLED | MF_GRAYED, WINAMP_OPTIONS_EQ, TEXT( "Equalizer\tAlt+G" ) );
AppendMenu( main_context_menu, MF_STRING | MF_DISABLED | MF_GRAYED, WINAMP_OPTIONS_VIDEO, TEXT( "Video\tAlt+V" ) );
AppendMenu( main_context_menu, MF_STRING, PLAINAMP_TOGGLE_CONSOLE, TEXT( "Console" ) );
AppendMenu( main_context_menu, MF_STRING, PLAINAMP_TOGGLE_MANAGER, TEXT( "Plugin Manager" ) );
/*
AppendMenu( main_context_menu, MF_STRING | MF_DISABLED | MF_GRAYED, MENU_MAIN_CONTEXT_MANAGER, TEXT( "Plugin Manager" ) );
AppendMenu( main_context_menu, MF_STRING | MF_DISABLED | MF_GRAYED, MENU_MAIN_CONTEXT_CONSOLE, TEXT( "Console" ) );
*/
AppendMenu( main_context_menu, MF_SEPARATOR | MF_DISABLED | MF_GRAYED, ( UINT_PTR )-1, NULL );
opts_context_menu = CreatePopupMenu();
AppendMenu( opts_context_menu, MF_STRING, WINAMP_OPTIONS_PREFS, TEXT( "Preferences \tCtrl+P" ) );
AppendMenu( main_context_menu, MF_STRING | MF_POPUP, ( UINT_PTR )opts_context_menu, TEXT( "Options" ) );
playback_context_menu = CreatePopupMenu();
AppendMenu( playback_context_menu, MF_STRING, WINAMP_BUTTON1, TEXT( "Previous \tZ" ) );
AppendMenu( playback_context_menu, MF_STRING, WINAMP_BUTTON2, TEXT( "Play\tX" ) );
AppendMenu( playback_context_menu, MF_STRING, WINAMP_BUTTON3, TEXT( "Pause\tC" ) );
AppendMenu( playback_context_menu, MF_STRING, WINAMP_BUTTON4, TEXT( "Stop\tV" ) );
AppendMenu( playback_context_menu, MF_STRING, WINAMP_BUTTON5, TEXT( "Next\tB" ) );
AppendMenu( main_context_menu, MF_STRING | MF_POPUP, ( UINT_PTR )playback_context_menu, TEXT( "Playback" ) );
AppendMenu( main_context_menu, MF_SEPARATOR | MF_DISABLED | MF_GRAYED, ( UINT_PTR )-1, NULL );
AppendMenu( main_context_menu, MF_STRING, WINAMP_FILE_QUIT, TEXT( "Exit" ) );
Toolbar::Create(); // This removes all buttons and status bars
//BuildMainStatus();
// =======================================================================================
// If this is not created a crash occurs
PlaylistView::Create();
Playlist::Create();
SetWindowPlacement( WindowMain, &WinPlaceMain );
return true;
#endif
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void About( HWND hParent )
{
// For info goto
// http://predef.sourceforge.net/precomp.html
TCHAR szBuildDetails[ 1000 ] = "";
#ifdef __GNUC__
_stprintf( szBuildDetails,
TEXT( "\n\n\nGNU GCC " __VERSION__ "\n" __DATE__ )
);
#else
# ifdef _MSC_VER
_stprintf(
szBuildDetails,
TEXT( "\n\n\nMicrosoft Visual C++ %i.%i\n" __DATE__ ),
_MSC_VER / 100 - 6,
( _MSC_VER % 100 ) / 10
);
# endif
#endif
TCHAR szBuffer[ 1000 ];
_stprintf(
szBuffer,
PLAINAMP_LONG_TITLE TEXT( "\n"
"\n"
"Copyright © 2005 Sebastian Pipping \n"
"<[email protected]>\n"
"\n"
"--> http://www.hartwork.org"
"%s"
),
szBuildDetails
);
MessageBox(
hParent,
szBuffer,
TEXT( "About" ),
MB_ICONINFORMATION
);
}
#define TRAY_MAIN_ID 13
#define TRAY_MSG ( WM_USER + 1 )
NOTIFYICONDATA nid;
bool AddTrayIcon( HWND hwnd )
{
ZeroMemory( &nid, sizeof( NOTIFYICONDATA ) );
nid.cbSize = sizeof( NOTIFYICONDATA );
nid.hWnd = hwnd;
nid.uID = TRAY_MAIN_ID;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.uCallbackMessage = TRAY_MSG;
nid.hIcon = LoadIcon( g_hInstance, TEXT( "IDI_ICON1" ) );
_tcscpy( nid.szTip, TEXT( "Plainamp" ) );
return ( Shell_NotifyIcon( NIM_ADD, &nid ) != 0 );
}
void RemoveTrayIcon()
{
Shell_NotifyIcon( NIM_DELETE, &nid );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndprocMain( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
// Tool windows are hidden on minimize/re-shown on restore
static bool bConsoleTodo = false;
static bool bManagerTodo = false;
static bool bRemoveIcon = false;
#ifdef NOGUI
//Console::Print("DLL > Main.cpp:WndprocMain() was called. But nothing will be done. \n");
#else
Console::Append( TEXT( "Main.cpp:WndprocMain was called" ) );
#endif
switch( message )
{
#ifdef NOGUI
//printf(" > WndprocMain message: %i\n", message);
#else
case WM_SETFOCUS:
// To re-"blue"
SetFocus( WindowPlaylist );
break;
case WM_CREATE:
// Note: [WindowMain] is not valid yet but [hwnd] is!
Console::Create(); // make the console window
PluginManager::Build(); // make the plugin window
break;
case WM_NOTIFY:
{
NMHDR * hdr = ( NMHDR * )lp;
switch( hdr->code )
{
case LVN_GETDISPINFO:
{
LV_DISPINFO * lpdi = ( LV_DISPINFO * )lp;
playlist->Fill( lpdi->item );
}
return 0;
/*
case LVN_ODCACHEHINT:
{
LPNMLVCACHEHINT lpCacheHint = (LPNMLVCACHEHINT)lParam;
/
This sample doesn't use this notification, but this is sent when the
ListView is about to ask for a range of items. On this notification,
you should load the specified items into your local cache. It is still
possible to get an LVN_GETDISPINFO for an item that has not been cached,
therefore, your application must take into account the chance of this
occurring.
/
}
return 0;
case LVN_ODFINDITEM:
{
LPNMLVFINDITEM lpFindItem = (LPNMLVFINDITEM)lParam;
/
This sample doesn't use this notification, but this is sent when the
ListView needs a particular item. Return -1 if the item is not found.
/
}
return 0;
*/
case NM_CUSTOMDRAW:
{
NMLVCUSTOMDRAW * custom = ( NMLVCUSTOMDRAW * )lp;
switch( custom->nmcd.dwDrawStage )
{
case CDDS_PREPAINT:
return CDRF_NOTIFYITEMDRAW;
case CDDS_ITEMPREPAINT:
return CDRF_NOTIFYSUBITEMDRAW;
case ( CDDS_SUBITEM | CDDS_ITEMPREPAINT ):
{
// This is the prepaint stage for an item. Here's where we set the
// item's text color. Our return value will tell Windows to draw the
// item itself, but it will use the new color we set here.
// We'll cycle the colors through red, green, and light blue.
if( custom->nmcd.dwItemSpec == playlist->GetCurIndex() )
{
custom->clrTextBk = RGB( 225, 225, 225 );
}
else
{
if( custom->nmcd.dwItemSpec & 1 )
custom->clrTextBk = RGB( 245, 248, 250 );
else
custom->clrTextBk = RGB( 255, 255, 255 );
}
if( custom->iSubItem == 0 )
custom->clrText = RGB( 255, 0, 0 );
else
custom->clrText = RGB( 0, 0, 0 );
/*
if ( (custom->nmcd.dwItemSpec % 3) == 0 )
crText = RGB(255,0,0);
else if ( (custom->nmcd.dwItemSpec % 3) == 1 )
crText = RGB(0,255,0);
else
crText = RGB(128,128,255);
// Store the color back in the NMLVCUSTOMDRAW struct.
custom->clrText = crText;
*/
// Tell Windows to paint the control itself.
}
/*
custom->clrText = RGB( 190, 190, 190 );
custom->clrTextBk = RGB( 255, 0, 0 );*/
return CDRF_DODEFAULT;
}
break;
}
/*
case RBN_CHILDSIZE:
{
NMREBARCHILDSIZE * chs = ( NMREBARCHILDSIZE * )lp;
const int width_client = chs->rcChild.right - chs->rcChild.left;
int diff = width_client - 120;
if( diff > 0 )
{
const int width_band = chs->rcBand.right - chs->rcBand.left;
// chs->rcChild.right = chs->rcChild.left + 120;
DEBUGF( 1000, "CHILDSIZE [%i] [%i]", chs->uBand, width_band );
const int client_band_diff = width_band - width_client;
chs->rcBand.right = chs->rcBand.left + 120 + client_band_diff;
// chs->uBand
REBARBANDINFO rbbi;
rbbi.cbSize = sizeof( REBARBANDINFO );
rbbi.fMask = RBBIM_SIZE;
rbbi.cx = 154; //width_band + diff;
LRESULT lResult = SendMessage(
rebar,
RB_SETBANDINFO,
chs->uBand,
( LPARAM )( REBARBANDINFO * )&rbbi
);
}
break;
}
*/
case RBN_HEIGHTCHANGE:
{
const int iRebarHeightBefore = iRebarHeight;
RECT r;
GetWindowRect( WindowRebar, &r );
iRebarHeight = r.bottom - r.top;
InvalidateRect( WindowRebar, NULL, TRUE );
InvalidateRect( WindowPlaylist, NULL, TRUE );
RECT client;
GetClientRect( WindowMain, &client );
PostMessage(
hwnd,
WM_SIZE,
SIZE_RESTORED,
( client.right - client.left ) << 16 |
( client.bottom - client.top )
);
break;
}
}
break;
}
case WM_SYSKEYDOWN:
switch( wp ) // [Alt]+[...]
{
case VK_UP:
case VK_DOWN:
SetFocus( WindowPlaylist );
SendMessage( WindowPlaylist, message, wp, lp );
break;
}
break;
case WM_KEYDOWN:
case WM_KEYUP:
SetFocus( WindowPlaylist );
SendMessage( WindowPlaylist, message, wp, lp );
break;
case WM_COMMAND:
{
const int code = HIWORD( wp );
switch( code )
{
case 1: // also == CBN_SELCHANGE
{
if( ( HWND )lp == WindowOrder )
{
LRESULT res = SendMessage( WindowOrder, CB_GETCURSEL, 0, 0 );
if( res == CB_ERR ) break;
Playback::Order::SetMode( ( int )res );
}
else if( ( HWND )lp == WindowEq )
{
LRESULT res = SendMessage( WindowEq, CB_GETCURSEL, 0, 0 );
if( res == CB_ERR ) break;
Playback::Eq::SetIndex( ( int )( res - 1 ) );
}
return WndprocWinamp( hwnd, message, wp, lp );
}
case 0:
{
// Menu
const int id = LOWORD( wp );
switch( id )
{
case MENU_MAIN_WINDOWS_CONSOLE:
Console::Popup();
break;
case MENU_MAIN_WINDOWS_MANAGER:
PluginManager::Popup();
break;
}
/*
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "default 1 id = <%i>" ), id );
MessageBox( 0, szBuffer, "", 0 );
*/
return WndprocWinamp( hwnd, message, wp, lp );
}
default:
return WndprocWinamp( hwnd, message, wp, lp );
}
break;
}
case WM_GETMINMAXINFO:
{
MINMAXINFO * mmi = ( MINMAXINFO * )lp;
mmi->ptMinTrackSize.x = 400;
mmi->ptMinTrackSize.y = 300;
return 0;
}
case WM_SIZE:
{
// Resize children
RECT client;
GetClientRect( WindowMain, &client );
const int iClientWidth = client.right - client.left;
const int iClientHeight = client.bottom - client.top;
const int iPlaylistHeight = iClientHeight - iRebarHeight - iStatusHeight;
if( WindowRebar )
MoveWindow( WindowRebar, 0, 0, iClientWidth, iRebarHeight, TRUE );
if( WindowPlaylist )
{
MoveWindow( WindowPlaylist, 0, iRebarHeight, iClientWidth, iPlaylistHeight, TRUE );
playlist->Resize( WindowMain );
}
if( WindowStatus )
MoveWindow( WindowStatus, 0, iRebarHeight + iPlaylistHeight, iClientWidth, iStatusHeight, TRUE );
break;
}
case WM_TIMER:
Playback::UpdateSeek();
break;
case WM_CONTEXTMENU:
PostMessage( hwnd, WM_COMMAND, WINAMP_MAINMENU, 0 );
break;
case WM_CLOSE:
{
// Clean shutdown
// Stop
Playback::Stop();
// Dsp
DspLock.Enter();
for( int d = active_dsp_count - 1; d >= 0; d-- )
{
DspLock.Leave();
active_dsp_mods[ d ]->Stop();
DspLock.Enter();
}
DspLock.Leave();
// Vis
VisLock.Enter();
for( int v = active_vis_count - 1; v >= 0; v-- )
{
VisLock.Leave();
active_vis_mods[ v ]->Stop();
VisLock.Enter();
}
VisLock.Leave();
}
break;
case WM_DESTROY:
{
// =======================================================================================
// Save playlist
/*
TCHAR * szPlaylistMind = new TCHAR[ iHomeDirLen + 12 + 1 ];
memcpy( szPlaylistMind, szHomeDir, iHomeDirLen * sizeof( TCHAR ) );
memcpy( szPlaylistMind + iHomeDirLen, TEXT( "Plainamp.m3u" ), 12 * sizeof( TCHAR ) );
szPlaylistMind[ iHomeDirLen + 12 ] = TEXT( '\0' );
Playlist::ExportPlaylistFile( szPlaylistMind );
delete [] szPlaylistMind;
*/
// =======================================================================================
cwpcWinPlaceMain.TriggerCallback();
cwpcWinPlaceMain.RemoveCallback();
Console::Destroy();
PluginManager::Destroy();
if( bRemoveIcon )
{
RemoveTrayIcon();
bRemoveIcon = false;
}
PostQuitMessage( 0 );
return 0;
}
case WM_ACTIVATEAPP:
{
if( wp != TRUE ) break;
// Also bring console/manager to front
const bool bConsoleVisible = ( IsWindowVisible( WindowConsole ) == TRUE );
const bool bManagerVisible = ( IsWindowVisible( WindowManager ) == TRUE );
const bool bMainTodo = ( bConsoleVisible || bManagerVisible );
if( bConsoleVisible ) BringWindowToTop( WindowConsole );
if( bManagerVisible ) BringWindowToTop( WindowManager );
if( bMainTodo ) BringWindowToTop( WindowMain );
break;
}
case WM_SYSCOMMAND:
switch( ( wp & 0xFFF0 ) )
{
case SC_CLOSE:
if( !SendMessage( WindowMain, WM_WA_IPC, 0, IPC_HOOK_OKTOQUIT ) )
{
return 0;
}
break;
case SC_MINIMIZE:
{
// Hide console/manager on minimize
bConsoleTodo = ( IsWindowVisible( WindowConsole ) == TRUE );
if( bConsoleTodo ) ShowWindow( WindowConsole, SW_HIDE );
bManagerTodo = ( IsWindowVisible( WindowManager ) == TRUE );
if( bManagerTodo ) ShowWindow( WindowManager, SW_HIDE );
if( bMinimizeToTray )
{
if( !bRemoveIcon )
{
bRemoveIcon = AddTrayIcon( hwnd );
}
ShowWindow( hwnd, FALSE );
return 0;
}
break;
}
case SC_RESTORE:
{
const LRESULT res = DefWindowProc( hwnd, message, wp, lp );
// Unhide console/manager
const bool bMainTodo = ( bConsoleTodo || bManagerTodo );
if( bConsoleTodo ) ShowWindow( WindowConsole, SW_SHOW );
if( bManagerTodo ) ShowWindow( WindowManager, SW_SHOW );
if( bMainTodo ) BringWindowToTop( WindowMain );
return res;
}
}
break;
case TRAY_MSG:
switch( lp )
{
case WM_RBUTTONDOWN: // TODO: context menu instead
case WM_LBUTTONDOWN:
if( IsWindowVisible( hwnd ) == FALSE )
{
ShowWindow( hwnd, TRUE );
}
break;
case WM_RBUTTONUP: // TODO: context menu instead
case WM_LBUTTONUP:
if( bRemoveIcon )
{
RemoveTrayIcon();
bRemoveIcon = false;
}
break;
}
return 0;
#endif
default:
return WndprocWinamp( hwnd, message, wp, lp );
}
return DefWindowProc( hwnd, message, wp, lp );
}
+51
View File
@@ -0,0 +1,51 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_MAIN_H
#define PA_MAIN_H
#include "Global.h"
#include "Winamp/wa_msgids.h"
// TODO
#define MENU_MAIN_WINDOWS_CONSOLE 41
#define MENU_MAIN_WINDOWS_MANAGER 42
#define MENU_MAIN_CONTEXT_MANAGER WINAMP_MAIN_WINDOW // first window, for gen_dl
#define MENU_MAIN_CONTEXT_CONSOLE WINAMP_OPTIONS_VIDEO // last window, for gen_template
#define PLAINAMP_TOGGLE_CONSOLE 50001
#define PLAINAMP_TOGGLE_MANAGER 50002
extern HWND WindowMain;
extern HMENU main_context_menu;
bool BuildMainWindow();
void About( HWND hParent );
LRESULT CALLBACK WndprocMain( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
#endif // PA_MAIN_H
+382
View File
@@ -0,0 +1,382 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Output.h"
#include "OutputPlugin.h"
#include "Console.h"
#include <time.h>
int iNullSampleRate;
int iNullSumBytesPerSample;
int iNullWrittenMillis;
bool bNullPlaying;
int bNullPaused;
DWORD dwNullOpenTimestamp;
DWORD dwNullPauseTimestamp;
const int NULL_DEFAULT_LATENCY = 1000;
int Output_Open( int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms );
void Output_Close();
int Output_Write( char * buf, int len );
int Output_CanWrite();
int Output_IsPlaying();
int Output_Pause( int pause );
void Output_SetVolume( int volume );
void Output_SetPan( int pan );
void Output_Flush( int t );
int Output_GetOutputTime();
int Output_GetWrittenTime();
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
Out_Module output_server = {
OUT_VER, // int version
"Plainamp Output Server", // char * description;
0x7fffffff, // int id
NULL, // HWND hMainWindow
NULL, // HINSTANCE hDllInstance
NULL, // void (*Config)(HWND hwndParent);
NULL, // void (*About)(HWND hwndParent);
NULL, // void (*Init)();
NULL, // void (*Quit)();
Output_Open, // int (*Open)(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms);
Output_Close, // void (*Close)();
Output_Write, // int (*Write)(char *buf, int len);
Output_CanWrite, // int (*CanWrite)();
Output_IsPlaying, // int (*IsPlaying)();
Output_Pause, // int (*Pause)(int pause);
Output_SetVolume, // void (*SetVolume)(int volume);
Output_SetPan, // void (*SetPan)(int pan);
Output_Flush, // void (*Flush)(int t);
Output_GetOutputTime, // int (*GetOutputTime)();
Output_GetWrittenTime, // int (*GetWrittenTime)();
};
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int Output_Open( int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms )
{
if( active_output_count > 0 )
{
// Maximum
int res = 0;
int res_temp;
for( int i = 0; i < active_output_count; i++ )
{
res_temp = active_output_plugins[ i ]->plugin->Open( samplerate, numchannels, bitspersamp, bufferlenms, prebufferms );
if( res_temp > res ) res = res_temp;
}
return res;
}
else
{
iNullSampleRate = samplerate;
iNullSumBytesPerSample = numchannels * ( bitspersamp / 8 );
iNullWrittenMillis = 0;
bNullPlaying = false;
bNullPaused = 0;
dwNullOpenTimestamp = GetTickCount();
return NULL_DEFAULT_LATENCY;
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void Output_Close()
{
if( active_output_count > 0 )
{
for( int i = 0; i < active_output_count; i++ )
{
active_output_plugins[ i ]->plugin->Close();
}
}
else
{
bNullPlaying = false;
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int Output_Write( char * buf, int len )
{
if( active_output_count > 0 )
{
// Maximum
int res = 0;
int res_temp;
for( int i = 0; i < active_output_count; i++ )
{
res_temp = active_output_plugins[ i ]->plugin->Write( buf, len );
if( res_temp > res ) res = res_temp;
}
return res;
}
else
{
if( iNullWrittenMillis == 0 )
{
dwNullOpenTimestamp = GetTickCount();
bNullPlaying = true;
}
iNullWrittenMillis += ( len / iNullSumBytesPerSample ) * 1000 / iNullSampleRate;
return 0; // 0 == Success
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int Output_CanWrite()
{
if( active_output_count > 0 )
{
// Minimum
int res = 0x7fffffff;
int res_temp;
for( int i = 0; i < active_output_count; i++ )
{
res_temp = active_output_plugins[ i ]->plugin->CanWrite();
if( res_temp < res ) res = res_temp;
}
return res;
}
else
{
const int diff = Output_GetWrittenTime() - Output_GetOutputTime();
if( diff >= NULL_DEFAULT_LATENCY )
{
return 0;
}
else
{
return ( NULL_DEFAULT_LATENCY - diff ) * iNullSumBytesPerSample * iNullSampleRate / 1000;
}
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int Output_IsPlaying()
{
if( active_output_count > 0 )
{
// Maximum
int res = 0;
int res_temp;
for( int i = 0; i < active_output_count; i++ )
{
res_temp = active_output_plugins[ i ]->plugin->IsPlaying();
if( res_temp > res ) res = res_temp;
}
return res;
}
else
{
return ( Output_GetOutputTime() < Output_GetWrittenTime() ) ? 1 : 0;
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int Output_Pause( int pause )
{
if( active_output_count > 0 )
{
// Maximum
int res = 0;
int res_temp;
for( int i = 0; i < active_output_count; i++ )
{
res_temp = active_output_plugins[ i ]->plugin->Pause( pause );
if( res_temp > res ) res = res_temp;
}
return res;
}
else
{
int res = bNullPaused;
if( pause && !bNullPaused )
{
// Playback should be paused
dwNullPauseTimestamp = GetTickCount();
bNullPaused = 1;
}
else if( !pause && bNullPaused )
{
// Playback should be continued
// Add the gap length to the open timestamp like no gap exists
dwNullOpenTimestamp += ( GetTickCount() - dwNullPauseTimestamp );
bNullPaused = 0;
}
return res; // Previous state
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void Output_SetVolume( int volume )
{
/* There was a call here with the volume value -666 that I could not see the source of,
so I added this check to see that we got a positive volume. */
if(volume >= 0)
{
// =======================================================================================
// The volume goes from 0 to 255
//TCHAR szBuffer[ 5000 ];
//_stprintf( szBuffer, TEXT( "DLL > Output_SetVolume <%i>" ), volume );
//Console::Append( szBuffer );
//Console::Append( TEXT( " " ) );
//Console::Print( "DLL > Output_SetVolume <%i>\n", volume );
// =======================================================================================
for( int i = 0; i < active_output_count; i++ )
{
active_output_plugins[ i ]->plugin->SetVolume( volume );
}
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void Output_SetPan( int pan )
{
for( int i = 0; i < active_output_count; i++ )
{
active_output_plugins[ i ]->plugin->SetPan( pan );
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void Output_Flush( int t )
{
if( active_output_count > 0 )
{
for( int i = 0; i < active_output_count; i++ )
{
active_output_plugins[ i ]->plugin->Flush( t );
}
}
else
{
dwNullOpenTimestamp = GetTickCount() - t;
iNullWrittenMillis = t;
}
}
////////////////////////////////////////////////////////////////////////////////
/// Returns the number of milliseconds the song would be at
/// if we had zero latency. This value is never bigger than
/// the one returned by Output_GetWrittenTime().
////////////////////////////////////////////////////////////////////////////////
int Output_GetOutputTime() // <= GetWrittenTime()
{
if( active_output_count > 0 )
{
// Minimum
int res = 0x7fffffff;
int res_temp;
for( int i = 0; i < active_output_count; i++ )
{
res_temp = active_output_plugins[ i ]->plugin->GetOutputTime();
if( res_temp < res ) res = res_temp;
}
return res;
}
else
{
if( bNullPlaying )
{
int res;
if( bNullPaused )
{
res = dwNullPauseTimestamp - dwNullOpenTimestamp;
}
else
{
res = GetTickCount() - dwNullOpenTimestamp;
}
return MIN( res, iNullWrittenMillis );
}
else
{
return 0;
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// Returns the number of milliseconds already written.
/// Due to latency this value is always bigger than
/// the value returned by Output_GetOutputTime().
////////////////////////////////////////////////////////////////////////////////
int Output_GetWrittenTime()
{
if( active_output_count > 0 )
{
// Maximum
int res = 0;
int res_temp;
for( int i = 0; i < active_output_count; i++ )
{
res_temp = active_output_plugins[ i ]->plugin->GetWrittenTime();
if( res_temp > res ) res = res_temp;
}
return res;
}
else
{
return iNullWrittenMillis;
}
}
+27
View File
@@ -0,0 +1,27 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_OUTPUT_H
#define PA_OUTPUT_H
#include "Global.h"
#include "Winamp/Out.h"
extern Out_Module output_server;
#endif // PA_OUTPUT_H
+316
View File
@@ -0,0 +1,316 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "OutputPlugin.h"
#include "Main.h"
#include "Unicode.h"
#include "Console.h"
#include "Config.h"
#include "Playback.h"
vector <OutputPlugin *> output_plugins; // extern
OutputPlugin ** active_output_plugins = NULL; // extern
int active_output_count = 0; // extern
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
OutputPlugin::OutputPlugin( TCHAR * szDllpath, bool bKeepLoaded ) : Plugin( szDllpath )
{
iHookerIndex = -1;
bActive = false;
iArrayIndex = -1;
plugin = NULL;
if( !Load() )
{
return;
}
////////////////////////////////////////////////////////////////////////////////
// Quick hack!!!
TCHAR * szBuffer = new TCHAR[ 500 ]; // NOT LOCAL!!!
_stprintf( szBuffer, TEXT( "OutputPluginActive___%s" ), GetFilename() );
ConfBool * cbActive = new ConfBool( &bActive, szBuffer, CONF_MODE_INTERNAL, false );
cbActive->Read();
printf("OutputPlugin > GetFilename() returned <%s>\n", szBuffer );
printf("OutputPlugin > We now have <bActive:%i> and <bKeepLoaded:%i>\n", bActive, bKeepLoaded );
if( bActive )
{
bActive = false;
Start();
}
else
{
if( !bKeepLoaded )
{
// Note: out_ds seems to do weird things
// when unloaded here!?
// So out_ds keeps loaded for now.
if( _tcscmp( GetFilename(), TEXT( "out_ds.dll" ) ) )
{
printf("OutputPlugin > Unload called from OutputPlugin::OutputPlugin\n");
Unload();
}
}
}
// Quick hack!!!
////////////////////////////////////////////////////////////////////////////////
output_plugins.push_back( this );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool OutputPlugin::Load()
{
if( IsLoaded() ) return true;
// (1) Load DLL
hDLL = LoadLibrary( GetFullpath() );
if( !hDLL ) return false;
// (2) Find export
WINAMP_OUTPUT_GETTER winampGetOutModule =
( WINAMP_OUTPUT_GETTER )GetProcAddress( hDLL, "winampGetOutModule" );
if( winampGetOutModule == NULL )
{
FreeLibrary( hDLL );
hDLL = NULL;
return false;
}
// (3) Get module
plugin = winampGetOutModule();
if( !plugin )
{
FreeLibrary( hDLL );
hDLL = NULL;
return false;
}
// (4) Process module
plugin->hDllInstance = hDLL;
plugin->hMainWindow = WindowMain;
if( !szName )
{
// Note: The prefix is not removed to hide their
// origin at Nullsoft! It just reads easier.
if( !strnicmp( plugin->description, "nullsoft ", 9 ) )
{
plugin->description += 9;
}
iNameLen = ( int )strlen( plugin->description );
szName = new TCHAR[ iNameLen + 1 ];
ToTchar( szName, plugin->description, iNameLen );
szName[ iNameLen ] = TEXT( '\0' );
}
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Loading <%s>, %s" ), GetFilename(), szName );
Console::Append( szBuffer );
Console::Append( TEXT( " " ) );
printf( ">>>Loading <%s>, %s\n" , GetFilename(), szName );
if( plugin->Init )
{
// We remove the WNDPROC things
#ifdef NOGUI
plugin->Init();
#else
// Init
const WNDPROC WndprocBefore = ( WNDPROC )GetWindowLong( WindowMain, GWL_WNDPROC );
plugin->Init();
const WNDPROC WndprocAfter = ( WNDPROC )GetWindowLong( WindowMain, GWL_WNDPROC );
if( WndprocBefore != WndprocAfter )
{
WndprocBackup = WndprocBefore;
iHookerIndex = iWndprocHookCounter++;
}
// Note: Plugins that use a wndproc hook need
// to be unloaded in the inverse loading order.
// This is due to the nature of wndproc hooking.
if( iHookerIndex != -1 )
{
Console::Append( TEXT( "Wndproc hook added (by plugin)" ) );
}
#endif
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool OutputPlugin::Unload()
{
if( !IsLoaded() ) return true;
if( bActive && Playback::IsPlaying() ) return false;
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Unloading <%s>" ), GetFilename() );
Console::Append( szBuffer );
Console::Append( TEXT( " " ) );
printf( ">>>Unloading <%s>\n" , GetFilename() );
// Quit
if( plugin )
{
if( plugin->Quit ) plugin->Quit();
plugin = NULL;
}
// Remove wndproc hook
if( ( iHookerIndex != -1 ) && ( iHookerIndex == iWndprocHookCounter - 1 ) )
{
// If we don't restore it the plugins wndproc will
// still be called which is not there anymore -> crash
SetWindowLong( WindowMain, GWL_WNDPROC, ( LONG )WndprocBackup );
Console::Append( TEXT( "Wndproc hook removed (by host)" ) );
Console::Append( TEXT( " " ) );
iHookerIndex = -1;
iWndprocHookCounter--;
}
FreeLibrary( hDLL );
hDLL = NULL;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool OutputPlugin::About( HWND hParent )
{
if( !IsLoaded() ) return false;
if( !plugin ) return false;
if( !plugin->About ) return false;
plugin->About( hParent );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool OutputPlugin::Config( HWND hParent )
{
if( !IsLoaded() ) return false;
if( !plugin ) return false;
if( !plugin->Config ) return false;
plugin->Config( hParent );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool OutputPlugin::Start()
{
//Console::Print( "OutputPlugin::Start() > Begin <IsLoaded():%i> <bActive:%i> <active_output_count:%i>\n",
// IsLoaded(), bActive, active_output_count );
if( !IsLoaded() ) return false;
if( bActive ) return true;
if( active_output_count )
{
active_output_plugins = ( OutputPlugin ** )realloc( active_output_plugins, ( active_output_count + 1 ) * sizeof( OutputPlugin * ) );
active_output_plugins[ active_output_count ] = this;
iArrayIndex = active_output_count;
active_output_count++;
}
else
{
active_output_plugins = ( OutputPlugin ** )malloc( sizeof( OutputPlugin * ) );
active_output_plugins[ 0 ] = this;
iArrayIndex = 0;
active_output_count = 1;
}
#ifndef NOGUI
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Output plugin <%s> activated" ), GetFilename() );
Console::Append( szBuffer );
Console::Append( TEXT( " " ) );
#else
Console::Print( "\n >>> Output plugin '%s' activated\n\n" , GetFilename() );
#endif
bActive = true;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool OutputPlugin::Stop()
{
if( !IsLoaded() ) return true;
if( !bActive ) return true;
const int iMaxIndex = active_output_count - 1;
if( iArrayIndex < iMaxIndex )
{
active_output_plugins[ iArrayIndex ] = active_output_plugins[ iMaxIndex ];
active_output_plugins[ iArrayIndex ]->iArrayIndex = iArrayIndex;
}
iArrayIndex = -1;
active_output_count--;
// TODO Flush?
// TODO Close?
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Output plugin <%s> deactivated" ), GetFilename() );
Console::Append( szBuffer );
Console::Append( TEXT( " " ) );
bActive = false;
return true;
}
+87
View File
@@ -0,0 +1,87 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_OUTPUT_PLUGIN_H
#define PA_OUTPUT_PLUGIN_H
#include "Global.h"
#include "Plugin.h"
#include "Winamp/Out.h"
#include <vector>
using namespace std;
typedef Out_Module * ( * WINAMP_OUTPUT_GETTER )( void );
class OutputPlugin;
extern vector <OutputPlugin *> output_plugins;
extern OutputPlugin ** active_output_plugins;
extern int active_output_count;
////////////////////////////////////////////////////////////////////////////////
/// Winamp output plugin wrapper
////////////////////////////////////////////////////////////////////////////////
class OutputPlugin : public Plugin
{
public:
OutputPlugin( TCHAR * szDllpath, bool bKeepLoaded );
bool Load();
bool Unload();
TCHAR * GetTypeString() { return TEXT( "Output" ); }
int GetTypeStringLen() { return 6; }
PluginType GetType() { return PLUGIN_TYPE_OUTPUT; }
inline bool IsActive() { return bActive; }
bool About( HWND hParent );
bool Config( HWND hParent );
bool Start();
bool Stop();
Out_Module * plugin; // Moved to public
private:
bool bActive;
int iArrayIndex;
// TODO
friend bool OpenPlay( TCHAR * szFilename, int iNumber );
friend int Output_Open( int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms );
friend void Output_Close();
friend int Output_Write( char * buf, int len );
friend int Output_CanWrite();
friend int Output_IsPlaying();
friend int Output_Pause( int pause );
friend void Output_SetVolume( int volume );
friend void Output_SetPan( int pan );
friend void Output_Flush( int t );
friend int Output_GetOutputTime();
friend int Output_GetWrittenTime();
};
#endif // PA_OUTPUT_PLUGIN_H
+243
View File
@@ -0,0 +1,243 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Path.h"
#include <ctype.h>
#include <vector>
using namespace std;
////////////////////////////////////////////////////////////////////////////////
/// Applies a virtual root to a filename
///
/// Example:
/// Rootpath: "C:\111\222\333\"
/// Filename before: "C:\111\444\test.mp3"
/// Filename after: "..\..\444\test.mp3"
////////////////////////////////////////////////////////////////////////////////
bool ApplyRootToFilename( TCHAR * szRootpath, TCHAR * szFilename )
{
// returns modified flag
int iFilenameLen = ( int )_tcslen( szFilename );
int iRootLen = ( int )_tcslen( szRootpath );
// Too short?
if( ( iRootLen < 2 ) || ( iFilenameLen < 4 ) )
{
return false;
}
// Ensure trailing backslash
bool bDelOnRet = false;
TCHAR * szFinalRoot;
TCHAR * szFinalRootBackup;
if( szRootpath[ iRootLen - 1 ] != TEXT( '\\' ) )
{
szFinalRoot = new TCHAR[ iRootLen + 2 ];
memcpy( szFinalRoot, szRootpath, iRootLen * sizeof( TCHAR ) );
memcpy( szFinalRoot + iRootLen, TEXT( "\\\0" ), 2 * sizeof( TCHAR ) );
iRootLen++;
szFinalRootBackup = szFinalRoot;
bDelOnRet = true;
}
else
{
szFinalRoot = szRootpath;
szFinalRootBackup = NULL;
bDelOnRet = false;
}
// Different drives?
if( _totlower( *szFilename ) != _totlower( *szFinalRoot ) )
{
if( bDelOnRet ) delete [] szFinalRootBackup;
return false;
}
// Skip drive
if( _tcsnicmp( szFilename, szFinalRoot, 3 ) )
{
szFinalRoot += 3;
iRootLen -= 3;
memmove( szFilename, szFilename + 3, ( iFilenameLen - 2 ) * sizeof( TCHAR ) ); // Plus \0
iFilenameLen -=3;
}
int iBackslashLast = -1;
int iCompLen; // Maximum chars to compare
if( iRootLen > iFilenameLen )
iCompLen = iFilenameLen;
else
iCompLen = iRootLen;
// Walk while equal
int i = 0;
while( i < iCompLen )
{
if( ( szFilename[ i ] == TEXT( '\\' ) ) && ( szFinalRoot[ i ] == TEXT( '\\' ) ) )
{
iBackslashLast = i;
i++;
}
else if( _totlower( szFilename[ i ] ) == _totlower( szFinalRoot[ i ] ) )
{
i++;
}
else
{
break;
}
}
// Does the filename contain the full root?
int iLevelDiff = 0;
if( i != iCompLen )
{
// Calculate level difference
for( i = iBackslashLast + 1; i < iRootLen; i++ )
{
if( szFinalRoot[ i ] == TEXT( '\\' ) )
{
iLevelDiff++;
}
}
}
if( iBackslashLast == -1 )
{
if( bDelOnRet ) delete [] szFinalRootBackup;
return false;
}
TCHAR * szSource = szFilename + iBackslashLast + 1;
if( iLevelDiff > 0 )
{
const int iExtraCharsForPrefix = ( 3 * iLevelDiff ) - iBackslashLast - 1;
const int iCharsToMove = iFilenameLen - iBackslashLast; // One more for '\0'
memmove( szSource + iExtraCharsForPrefix, szSource, sizeof( TCHAR ) * iCharsToMove );
TCHAR * szWalk = szFilename;
while( iLevelDiff-- )
{
memcpy( szWalk, TEXT( "..\\" ), 3 * sizeof( TCHAR ) );
szWalk += 3;
}
}
else
{
const int iCharsToMove = iFilenameLen - iBackslashLast; // One more for '\0'
memmove( szFilename, szSource, sizeof( TCHAR ) * iCharsToMove );
}
if( bDelOnRet ) delete [] szFinalRootBackup;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// Compresses filenames (inplace)
///
/// Example:
/// Before "C:\111\222\..\333\.\444\..\..\test.mp3"
/// After "C:\111\test.mp3"
////////////////////////////////////////////////////////////////////////////////
bool UnbloatFilename( TCHAR * szFullpath, bool bFixTooDeep )
{
int iLen = ( int )_tcslen( szFullpath );
bool bModified = false;
// Exclude drive letter from conversion "C:\"
if( ( iLen > 3 ) && !_tcsnicmp( szFullpath + 1, TEXT( ":\\" ), 2 ) )
{
szFullpath += 3;
iLen -= 3;
}
vector< TCHAR * > after_backslash;
TCHAR * end = szFullpath + iLen;
TCHAR * szWalk = szFullpath;
while( true )
{
if( !_tcsnicmp( szWalk, TEXT( "..\\" ), 3 ) )
{
TCHAR * szAfterBackslashLast;
if( after_backslash.empty() )
{
// Getting here means we go deeper than root level e.g. "../test"
if( bFixTooDeep )
{
szAfterBackslashLast = szWalk;
}
else
{
break;
}
}
else
{
szAfterBackslashLast = after_backslash.back();
after_backslash.pop_back();
}
const int iBytesToCopy = end - szWalk - ( 3 * sizeof( TCHAR ) );
const int iBytesLess = szWalk + ( 3 * sizeof( TCHAR ) ) - szAfterBackslashLast;
memmove( szAfterBackslashLast, szWalk + 3, iBytesToCopy );
char * byte_end = ( char * )end;
byte_end -= iBytesLess;
end = byte_end;
*end = TEXT( '\0' );
szWalk = szAfterBackslashLast;
bModified = true;
}
else if( !_tcsnicmp( szWalk, TEXT( ".\\" ), 2 ) )
{
const int iBytesToCopy = end - szWalk - ( 2 * sizeof( TCHAR ) );
memmove( szWalk, szWalk + 2, iBytesToCopy );
end -= 2;
*end = TEXT( '\0' );
bModified = true;
}
else
{
if( szWalk >= end ) break;
after_backslash.push_back( szWalk );
// Jump after next backslash
while( ( szWalk < end ) && ( *szWalk != TEXT( '\\' ) ) ) szWalk++;
szWalk++;
}
}
return bModified;
}
+31
View File
@@ -0,0 +1,31 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_PATH_H
#define PA_PATH_H
#ifndef PLAINAMP_TESTING
# include "Global.h"
#else
# include "../Testing/GlobalTest.h"
#endif
bool ApplyRootToFilename( TCHAR * szRootpath, TCHAR * szFilename );
bool UnbloatFilename( TCHAR * szFullpath, bool bFixTooDeep );
#endif // PA_PATH_H
+804
View File
@@ -0,0 +1,804 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Playback.h"
#include "InputPlugin.h"
#include "Output.h"
#include "Playlist.h"
#include "Console.h"
#include "Unicode.h"
#include "Rebar.h"
#include "Main.h"
#include "Config.h"
#include "Status.h"
int iCurVol = 255;
ConfIntMinMax ciCurVol( &iCurVol, TEXT( "Volume" ), CONF_MODE_INTERNAL, 255, 0, 255 );
int iCurPan = 0;
ConfIntMinMax ciCurPan( &iCurPan, TEXT( "Panning" ), CONF_MODE_INTERNAL, 0, -127, 127 );
#define VOLUME_STEP ( 255 / 10 )
bool bPlaying = false;
bool bPaused = false;
bool bTimerRunning = false;
// Only for reference comparison!!!
TCHAR * szCurrentFilename = NULL;
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
// =======================================================================================
// The timer that calls WndprocMain every second
void EnableTimer( bool bEnabled )
{
// Return if the timer is already activated
if( bEnabled == bTimerRunning ) return;
if( bEnabled )
{
SetTimer( WindowMain, TIMER_SEEK_UPDATE, 1000, NULL );
Console::Print( "EnableTimer > Activated\n" );
}
else
{
KillTimer( WindowMain, TIMER_SEEK_UPDATE );
StatusReset();
Console::Print( "EnableTimer > Killed\n" );
}
bTimerRunning = bEnabled;
}
// =======================================================================================
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
bool OpenPlay( TCHAR * szFilename, int iNumber )
{
// =======================================================================================
#ifdef NOGUI
//Console::Print( "Playback.cpp: OpenPlay > Begin <%i> <%s>\n" , iNumber, szFilename );
#else
TCHAR sszBuffer[ 5000 ];
_stprintf( sszBuffer, TEXT( "Playback.cpp: OpenPlay was called <%i> <%s>" ), iNumber, szFilename );
Console::Append( sszBuffer );
#endif
// =======================================================================================
// =======================================================================================
// Get the right input plugin
// ---------------------------------------------------------------------------------------
if( !szFilename ) return false;
szCurrentFilename = szFilename;
// ---------------------------------------------------------------------------------------
// TODO: non-file support
// ---------------------------------------------------------------------------------------
// Get file extension
const int iLen = ( int )_tcslen( szFilename );
TCHAR * walk = szFilename + iLen - 1;
while( ( walk >= szFilename ) && ( *walk != TEXT( '.' ) ) ) walk--;
walk++;
// ---------------------------------------------------------------------------------------
const int iExtLen = ( int )_tcslen( walk );
TCHAR * szExt = new TCHAR[ iExtLen + 1 ];
memcpy( szExt, walk, iExtLen * sizeof( TCHAR ) );
szExt[ iExtLen ] = TEXT( '\0' );
// ---------------------------------------------------------------------------------------
// Compare the extension to the supported extension by the current input plugins
map <TCHAR *, InputPlugin *, TextCompare>::iterator iter =
ext_map.find( szExt );
delete [] szExt;
if( iter == ext_map.end() )
{
Console::Append( TEXT( "ERROR: Extension not supported" ) );
Console::Append( " " );
Console::Print("OpenPlay > ERROR: Extension not supported\n");
return false;
}
// ---------------------------------------------------------------------------------------
// Now that we know which input pugin to use we set that one as active
InputPlugin * old_input = active_input_plugin; // Save the last one, if any
active_input_plugin = iter->second;
Console::Print("OpenPlay > Input plugin '%s' activated\n", active_input_plugin->GetFilename());
// =======================================================================================
if( old_input )
{
// if( active_input_plugin != old_input ) ----> TODO unload old plugin
// Some output plugins require a call to Close() before each
// call to Open(). Calling Input::Stop() will make the input plugin
// call Output::Close() and thus solve this problem.
old_input->plugin->Stop();
}
if( !active_input_plugin->plugin )
{
Console::Append( TEXT( "ERROR: Input plugin is NULL" ) );
Console::Append( " " );
Console::Print("OpenPlay > ERROR: Input plugin is NULL\n");
return false;
}
// Connect
//Console::Print( "OpenPlay > OutMod\n" );
active_input_plugin->plugin->outMod = &output_server; // output->plugin;
// =======================================================================================
// Re-apply volume and panning
//active_input_plugin->plugin->SetVolume( iCurVol );
//active_input_plugin->plugin->SetPan( iCurPan );
//Playback::Eq::Reapply();
// =======================================================================================
// Play
#ifdef PA_UNICODE
// Filename
const int iFilenameLen = _tcslen( szFilename );
char * szTemp = new char[ iFilenameLen + 1 ];
ToAnsi( szTemp, szFilename, iFilenameLen );
szTemp[ iFilenameLen ] = '\0';
// Ansi Title
char szAnsiTitle[ 2000 ] = "\0";
int length_in_ms;
active_input_plugin->plugin->GetFileInfo( szTemp, szAnsiTitle, &length_in_ms );
const int iAnsiTitleLen = strlen( szAnsiTitle );
// Unicode title
TCHAR szTitle[ 2000 ];
ToTchar( szTitle, szAnsiTitle, iFilenameLen, iAnsiTitleLen );
szTitle[ iAnsiTitleLen ] = TEXT( "\0" );
active_input_plugin->plugin->Play( szTemp );
delete [] szTemp;
#else
// =======================================================================================
// Play the file
// ---------------------------------------------------------------------------------------
// Title
TCHAR szTitle[ 2000 ] = TEXT( "\0" );
int length_in_ms;
//Console::Print( "OpenPlay > GetFileInfo\n" );
active_input_plugin->plugin->GetFileInfo( szFilename, szTitle, &length_in_ms );
//Console::Print( "OpenPlay > Play\n" );
active_input_plugin->plugin->Play( szFilename );
// =======================================================================================
#endif
bPlaying = true;
bPaused = false;
// =======================================================================================
// Title
//TCHAR szBuffer[ 5000 ];
//_stprintf( szBuffer, TEXT( "%i. %s - Plainamp" ), iNumber, szTitle );
//SetWindowText( WindowMain, szBuffer );
// =======================================================================================
/*
TCHAR * szBasename = szFilename + uLen - 1;
while( ( szBasename > szFilename ) && ( *szBasename != TEXT( '\\' ) ) ) szBasename--;
szBasename++;
*/
// Timer ON
//EnableTimer( true );
//Console::Print( "OpenPlay > End\n" );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback_PrevOrNext( bool bPrevOrNext )
{
// todo: prev/next in pause mode?
if( !active_input_plugin ) return false;
if( !active_input_plugin->plugin ) return false;
int iNextIndex = playlist->GetCurIndex();
int iMaxIndex = playlist->GetMaxIndex();
if( iMaxIndex < 0 || iNextIndex < 0 ) return false;
bool res;
if( bPrevOrNext )
res = Playback::Order::Prev( iNextIndex, iMaxIndex );
else
res = Playback::Order::Next( iNextIndex, iMaxIndex );
if( res )
{
if( bPlaying )
{
// NOT TWICE active_input_plugin->plugin->Stop();
bPlaying = false;
bPaused = false;
// Timer OFF
EnableTimer( false );
}
TCHAR * szFilename = Playlist::GetFilename( iNextIndex );
if( !szFilename ) return false;
playlist->SetCurIndex( iNextIndex );
return OpenPlay( szFilename, iNextIndex + 1 );
}
else
{
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Prev()
{
return Playback_PrevOrNext( true );
}
////////////////////////////////////////////////////////////////////////////////
// Play the file
////////////////////////////////////////////////////////////////////////////////
bool Playback::Play()
{
static int iLastIndex = -1;
// ---------------------------------------------------------------------------------------
#ifndef NOGUI
TCHAR sszBuffer[ 5000 ];
_stprintf( sszBuffer, TEXT( "Playback::Play() with bPlaying <%i>\n" ), bPlaying );
Console::Append( sszBuffer );
Console::Append( TEXT( " " ) );
#else
//Console::Print( "Playback::Play() > Begin <%i>\n" , bPlaying );
#endif
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
if( bPlaying ) // If we are currently playing a file
{
if( !active_input_plugin ) return false;
if( !active_input_plugin->plugin ) return false;
const int iIndex = playlist->GetCurIndex();
if( iIndex < 0 ) return false;
/*
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "OLD [%i] NEW [%i]" ), iLastIndex, iIndex );
SetWindowText( WindowMain, szBuffer );
*/
// If we are not playing the same track/file as before
TCHAR * szFilename = Playlist::GetFilename( iIndex );
if( szFilename != szCurrentFilename )
{
// New track!
// Stop
// NOT TWICE active_input_plugin->plugin->Stop();
// Timer OFF
//EnableTimer( false );
// Get filename
if( !szFilename )
{
Console::Append( TEXT( "ERROR: Could not resolve filename" ) );
Console::Append( " " );
return false;
}
// Play
iLastIndex = iIndex;
bPlaying = OpenPlay( szFilename, iIndex + 1 );
bPaused = false;
}
else
{
// Same track!
if( bPaused )
{
// Unpause
active_input_plugin->plugin->UnPause();
bPaused = false;
// Timer ON
//EnableTimer( true );
}
else
{
// Restart at beginning
active_input_plugin->plugin->SetOutputTime( 0 );
}
}
}
// =======================================================================================
else // we are not currently playing
{
const int iIndex = playlist->GetCurIndex();
if( iIndex < 0 ) return false;
// Get filename
TCHAR * szFilename = Playlist::GetFilename( iIndex );
// =======================================================================================
//bool bPlaying = false;
//TCHAR * szFilename = TEXT("C:\Files\Spel och spelfusk\Console\Gamecube\Code\vgmstream (isolate ast)\Music\demo36_02.ast");
//bPlaying = OpenPlay( szFilename, 1 );
//bPlaying = OpenPlay( szFilename, iIndex + 1 );
//Console::Append( TEXT( "Playback.cpp:Playback::Play() called OpenPlay" ) );
// =======================================================================================
if( !szFilename )
{
Console::Append( TEXT( "ERROR: Could not resolve filename" ) );
Console::Append( " " );
return false;
}
#ifndef NOGUI
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Playback.cpp: Play() got the filename <%s>" ), szFilename);
Console::Append( szBuffer );
//Console::Append( TEXT( " " ) );
#else
//Console::Print( "Playback::Play() > Filename <%s>\n", szFilename);
#endif
// Play
iLastIndex = iIndex;
bPlaying = OpenPlay( szFilename, iIndex + 1 );
bPaused = false;
}
return true;
}
// =======================================================================================
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Pause()
{
if( !bPlaying ) return false;
if( !active_input_plugin ) return false;
if( !active_input_plugin->plugin ) return false;
if( bPaused )
{
// Unpause
active_input_plugin->plugin->UnPause();
bPaused = false;
// Timer ON
//EnableTimer( true );
}
else
{
// Pause
active_input_plugin->plugin->Pause();
bPaused = true;
// Timer OFF
//EnableTimer( false );
}
// Console::Append( TEXT( "Playback::Pause" ) );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Stop()
{
if( !bPlaying ) return false;
// ---------------------------------------------------------------------------------------
// Stop
if( active_input_plugin && active_input_plugin->plugin )
{
active_input_plugin->plugin->Stop();
}
active_input_plugin = NULL; // QUICK FIX
// ---------------------------------------------------------------------------------------
bPlaying = false;
bPaused = false;
// Timer OFF > It was never turned on
//EnableTimer( false );
// Reset seekbar > We don't need this
//Playback::UpdateSeek();
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Next()
{
return Playback_PrevOrNext( false );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::IsPlaying()
{
return bPlaying;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::IsPaused()
{
return bPaused;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
//int getlength();
//int getoutputtime();
bool Playback::UpdateSeek()
{
#ifdef NOGUI
printf( "Playback::UpdateSeek > Begin\n" );
if( active_input_plugin )
{
printf( "GetLength() > Begin\n" );
const int ms_len = active_input_plugin->plugin->GetLength();
//const int ms_cur = active_input_plugin->plugin->GetOutputTime();
//const int ms_len = getlength();
//const int ms_cur = getoutputtime();
//printf( "Current position is <%i of %i>\n", ms_cur, ms_len );
}
return true;
#else
static bool bSliderEnabledBefore = false;
bool bSliderEnabledAfter;
//if( !WindowSeek ) return false;
int iVal = 0;
// If it has not been set
if( !active_input_plugin || !active_input_plugin->plugin )
{
if( bSliderEnabledBefore )
{
// Update slider
PostMessage( WindowSeek, TBM_SETPOS, ( WPARAM )( TRUE ), iVal );
// Disable slider
EnableWindow( WindowSeek, FALSE );
bSliderEnabledBefore = false;
}
}
else
{
const int ms_len = active_input_plugin->plugin->GetLength();
if( ms_len )
{
const int ms_cur = active_input_plugin->plugin->GetOutputTime();
iVal = ( ms_cur * 1000 ) / ms_len;
if( iVal > 1000 ) iVal = 0;
// =======================================================================================
//TCHAR szBuffer[ 5000 ];
//_stprintf( szBuffer, TEXT( "Current position is <%i of %i>" ), ms_cur, ms_len );
//Console::Append( szBuffer );
//Console::Append( TEXT( " " ) );
printf( "Current position is <%i of %i>\n", ms_cur, ms_len );
// =======================================================================================
}
if( !bSliderEnabledBefore )
{
EnableWindow( WindowSeek, TRUE );
bSliderEnabledBefore = true;
}
// Update slider
PostMessage( WindowSeek, TBM_SETPOS, ( WPARAM )( TRUE ), iVal );
}
return true;
#endif
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int Playback::PercentToMs( float fPercent )
{
if( !active_input_plugin ) return -1;
if( !active_input_plugin->plugin ) return -1;
const int ms_len = active_input_plugin->plugin->GetLength();
const int ms_res = ( int )( ms_len * fPercent / 100.0f );
return ms_res;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::SeekPercent( float fPercent )
{
// TODO update slider, NOT HERE!!!
if( !bPlaying ) return false;
if( bPaused ) return false; // TODO: apply seek when unpausing
if( !active_input_plugin ) return false;
if( !active_input_plugin->plugin ) return false;
if( fPercent < 0.0f )
fPercent = 0.0f;
else if( fPercent > 100.0f )
fPercent = 100.0f;
const int ms_len = active_input_plugin->plugin->GetLength();
const int ms_cur = ( int )( ms_len * fPercent / 100.0f );
active_input_plugin->plugin->SetOutputTime( ms_cur );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool SeekRelative( int ms )
{
if( !bPlaying ) return false;
if( bPaused ) return false; // TODO: apply seek when unpausing
if( !active_input_plugin ) return false;
if( !active_input_plugin->plugin ) return false;
const int ms_len = active_input_plugin->plugin->GetLength();
const int ms_old = active_input_plugin->plugin->GetOutputTime();
int ms_new = ms_old + ms;
if( ms_new < 0 )
ms_new = 0;
else if( ms_new > ms_len )
ms_new = ms_len;
if( ms_new == ms_old ) return true;
active_input_plugin->plugin->SetOutputTime( ms_new );
/*
// PROGRESS
// PostMessage( hwnd, PBM_SETPOS , ( WPARAM )( iVal ), 0 );
// TARCKBAR
PostMessage( wnd_pos, TBM_SETPOS, ( WPARAM )( TRUE ), ms_cur * 1000 / ms_len );
*/
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Forward()
{
return SeekRelative( 5000 );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Rewind()
{
return SeekRelative( -5000 );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void Playback::NotifyTrackEnd()
{
bPlaying = false;
bPaused = false;
// Timer
EnableTimer( false );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int Playback::Volume::Get()
{
return iCurVol;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
inline void Playback_Volume_Set( int iVol )
{
if( active_input_plugin && active_input_plugin->plugin )
{
active_input_plugin->plugin->SetVolume( iVol );
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Volume::Set( int iVol )
{
const int iCurVolBackup = iCurVol;
iCurVol = iVol;
ciCurVol.MakeValidPull();
if( iCurVol != iCurVolBackup )
{
Playback_Volume_Set( iCurVol );
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Volume::Up()
{
if( ciCurVol.IsMax() ) return true;
const int iCurVolBackup = iCurVol;
iCurVol += VOLUME_STEP;
ciCurVol.MakeValidPull();
if( iCurVol != iCurVolBackup )
{
Console::Append( TEXT( "Volume UP" ) );
Playback_Volume_Set( iCurVol );
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Volume::Down()
{
if( ciCurVol.IsMin() ) return true;
const int iCurVolBackup = iCurVol;
iCurVol -= VOLUME_STEP;
ciCurVol.MakeValidPull();
if( iCurVol != iCurVolBackup )
{
Console::Append( TEXT( "Volume DOWN" ) );
Playback_Volume_Set( iCurVol );
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int Playback::Pan::Get()
{
return iCurPan;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Pan::Set( int iPan )
{
const int iCurPanBackup = iCurPan;
iCurPan = iPan;
ciCurPan.MakeValidPull();
if( ( iCurPan != iCurPanBackup ) && active_input_plugin && active_input_plugin->plugin )
{
active_input_plugin->plugin->SetPan( iCurPan );
}
return true;
}
+106
View File
@@ -0,0 +1,106 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_PLAYBACK_H
#define PA_PLAYBACK_H
#include "Global.h"
#define ORDER_SINGLE 0
#define ORDER_SINGLE_REPEAT 1
#define ORDER_NORMAL 2
#define ORDER_NORMAL_REPEAT 3
#define ORDER_INVERSE 4
#define ORDER_INVERSE_REPEAT 5
#define ORDER_RANDOM 6
#define ORDER_FIRST ORDER_SINGLE
#define ORDER_LAST ORDER_RANDOM
#define ORDER_DEFAULT ORDER_NORMAL_REPEAT
#define TIMER_SEEK_UPDATE 1
typedef bool ( * PresetCallback )( TCHAR * );
namespace Playback
{
bool Prev();
bool Play();
bool Pause();
bool Stop();
bool Next();
bool IsPlaying();
bool IsPaused();
bool UpdateSeek();
int PercentToMs( float fPercent );
bool SeekPercent( float fPercent );
bool Forward();
bool Rewind();
void NotifyTrackEnd();
namespace Volume
{
int Get();
bool Set( int iVol );
bool Up();
bool Down();
};
namespace Pan
{
int Get();
bool Set( int iPan );
};
namespace Order
{
int GetCurMode();
bool SetMode( int iMode );
TCHAR * GetModeName( int iMode );
// int GetModeNameLen( int iMode );
bool Next( int & iCur, int iMax );
bool Prev( int & iCur, int iMax );
};
namespace Eq
{
// 63 -> -12db
// 31 -> 0
// 0 -> +12db
// bool Get( char * eq_data );
// bool Set( bool bOn, char * pData, int iPreamp );
int GetCurIndex();
bool SetIndex( int iPresetIndex );
bool Reapply();
bool ReadPresets( PresetCallback AddPreset );
};
};
#endif // PA_PLAYBACK_H
+223
View File
@@ -0,0 +1,223 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Playback.h"
#include "InputPlugin.h"
#include "Console.h"
#include "Config.h"
#include <vector>
using namespace std;
vector <char *> eq_vec;
// Note: CurPresetFixed will be renamed to CurPreset when
// custom presets are implemented. This hopefully avoids
// migration trouble.
int iCurPreset; // -1 means EQ off
ConfInt ciCurPreset( &iCurPreset, TEXT( "CurPresetFixed" ), CONF_MODE_INTERNAL, -1 );
bool bPreventDistortion; // Automatic preamp adjustment
ConfBool cbPreventDistortion( &bPreventDistortion, TEXT( "PreventDistortion" ), CONF_MODE_PUBLIC, true );
////////////////////////////////////////////////////////////////////////////////
// PRE valid index
////////////////////////////////////////////////////////////////////////////////
void Playback_Eq_Set( int iPresetIndex )
{
if( active_input_plugin && active_input_plugin->plugin )
{
if( iPresetIndex == -1 ) // == EQ disabled
{
char data[ 10 ] = { 31, 31, 31, 31, 31, 31, 31, 31, 31, 31 };
active_input_plugin->plugin->EQSet( 0, data, 31 );
}
else
{
char data[ 10 ];
memcpy( data, eq_vec[ iPresetIndex ], sizeof( char ) * 10 );
if( bPreventDistortion )
{
// Search minimum (most amplifying band)
int iMin = 63;
int i;
for( i = 0; i < 10; i++ )
{
if( data[ i ] < iMin ) iMin = data[ i ];
}
if( iMin < 31 ) // Possible distortion
{
// Adjust preamp to prevent distortion
active_input_plugin->plugin->EQSet( 1, data, 31 + ( 31 - iMin ) );
}
else
{
if( iMin > 31 ) // Lower than necessary
{
// Push to zero level so we get
// more volume without distortion
const int iSub = iMin - 31;
for( i = 0; i < 10; i++ )
{
data[ i ] -= iSub;
}
}
active_input_plugin->plugin->EQSet( 1, data, 31 );
}
}
else
{
active_input_plugin->plugin->EQSet( 1, data, 31 );
}
}
}
}
/*
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Eq::Set( bool bOn, char * pData, int iPreamp )
{
if( active_input_plugin && active_input_plugin->plugin )
{
char data[ 10 ];
memcpy( data, pData, sizeof( char ) * 10 );
active_input_plugin->plugin->EQSet( bOn ? 1 : 0, data, iPreamp );
}
return true;
}
*/
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int Playback::Eq::GetCurIndex()
{
return iCurPreset;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Eq::SetIndex( int iPresetIndex )
{
if( iPresetIndex >= ( int )eq_vec.size() ) return false;
Playback_Eq_Set( iPresetIndex );
iCurPreset = iPresetIndex;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Eq::Reapply()
{
Playback_Eq_Set( iCurPreset );
return true;
}
// Note: Most of these are the exact presets used in Winamp.
// I do not expect any legal trouble with this but
// in case I am wrong please let me know and I will
// remove them.
char eq_classical [ 10 ] = { 31, 31, 31, 31, 31, 31, 44, 44, 44, 48 };
char eq_club [ 10 ] = { 31, 31, 26, 22, 22, 22, 26, 31, 31, 31 };
char eq_dance [ 10 ] = { 16, 20, 28, 32, 32, 42, 44, 44, 32, 32 };
char eq_full_bass [ 10 ] = { 16, 16, 16, 22, 29, 39, 46, 49, 50, 50 };
char eq_full_bass_treble[ 10 ] = { 20, 22, 31, 44, 40, 29, 18, 14, 12, 12 };
char eq_full_treble [ 10 ] = { 48, 48, 48, 39, 27, 14, 6, 6, 6, 4 };
char eq_headphones [ 10 ] = { 24, 14, 23, 38, 36, 29, 24, 16, 11, 8 };
char eq_laptop [ 10 ] = { 24, 14, 23, 38, 36, 29, 24, 16, 11, 8 };
char eq_large_hall [ 10 ] = { 15, 15, 22, 22, 31, 40, 40, 40, 31, 31 };
char eq_live [ 10 ] = { 40, 31, 25, 23, 22, 22, 25, 27, 27, 28 };
char eq_more_bass [ 10 ] = { 22, 22, 22, 22, 22, 22, 26, 31, 31, 31 };
char eq_party [ 10 ] = { 20, 20, 31, 31, 31, 31, 31, 31, 20, 20 };
char eq_pop [ 10 ] = { 35, 24, 20, 19, 23, 34, 36, 36, 35, 35 };
char eq_reggae [ 10 ] = { 31, 31, 33, 42, 31, 21, 21, 31, 31, 31 };
char eq_rock [ 10 ] = { 19, 24, 41, 45, 38, 25, 17, 14, 14, 14 };
char eq_ska [ 10 ] = { 36, 40, 39, 33, 25, 22, 17, 16, 14, 16 };
char eq_soft [ 10 ] = { 24, 29, 34, 36, 34, 25, 18, 16, 14, 12 };
char eq_soft_rock [ 10 ] = { 25, 25, 28, 33, 39, 41, 38, 33, 27, 17 };
char eq_techno [ 10 ] = { 19, 22, 31, 41, 40, 31, 19, 16, 16, 17 };
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Eq::ReadPresets( PresetCallback AddPreset )
{
if( AddPreset == NULL ) return false;
eq_vec.push_back( eq_classical ); AddPreset( TEXT( "Classical" ) );
eq_vec.push_back( eq_club ); AddPreset( TEXT( "Club" ) );
eq_vec.push_back( eq_dance ); AddPreset( TEXT( "Dance" ) );
eq_vec.push_back( eq_full_bass ); AddPreset( TEXT( "Full Bass" ) );
eq_vec.push_back( eq_full_bass_treble ); AddPreset( TEXT( "Full Bass & Treble" ) );
eq_vec.push_back( eq_full_treble ); AddPreset( TEXT( "Full Treble" ) );
eq_vec.push_back( eq_headphones ); AddPreset( TEXT( "Headphones" ) );
eq_vec.push_back( eq_laptop ); AddPreset( TEXT( "Laptop Speakers" ) );
eq_vec.push_back( eq_large_hall ); AddPreset( TEXT( "Large Hall" ) );
eq_vec.push_back( eq_live ); AddPreset( TEXT( "Live" ) );
eq_vec.push_back( eq_more_bass ); AddPreset( TEXT( "More Bass" ) );
eq_vec.push_back( eq_party ); AddPreset( TEXT( "Party" ) );
eq_vec.push_back( eq_pop ); AddPreset( TEXT( "Pop" ) );
eq_vec.push_back( eq_reggae ); AddPreset( TEXT( "Reggae" ) );
eq_vec.push_back( eq_rock ); AddPreset( TEXT( "Rock" ) );
eq_vec.push_back( eq_ska ); AddPreset( TEXT( "Ska" ) );
eq_vec.push_back( eq_soft ); AddPreset( TEXT( "Soft" ) );
eq_vec.push_back( eq_soft_rock ); AddPreset( TEXT( "Soft Rock" ) );
eq_vec.push_back( eq_techno ); AddPreset( TEXT( "Techno" ) );
// Fix invalid indices
if( iCurPreset < -1 )
{
iCurPreset = -1;
}
else
{
const int iLen = ( int )eq_vec.size();
if( iCurPreset >= iLen )
{
iCurPreset = iLen - 1;
}
}
// TODO load/save eqf files
// GPL eqf loading from koders.com
// equalizer.c / xmms2 A Gtk2 port of xmms.(xmms2)
// equalizer.c / Digital Disco System(dds)
return true;
}
+205
View File
@@ -0,0 +1,205 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Playback.h"
#include "Config.h"
#include <time.h>
#include <stdlib.h>
int iCurOrder = ORDER_DEFAULT;
ConfIntMinMax ciCurOrder( &iCurOrder, TEXT( "Order" ), CONF_MODE_INTERNAL, ORDER_DEFAULT, ORDER_FIRST, ORDER_LAST );
bool bRandomReady = false;
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int Playback::Order::GetCurMode()
{
return iCurOrder;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Order::SetMode( int iMode )
{
iCurOrder = iMode;
ciCurOrder.MakeValidDefault();
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
TCHAR * Playback::Order::GetModeName( int iMode )
{
switch( iMode )
{
case ORDER_SINGLE: return TEXT( " Single" );
case ORDER_SINGLE_REPEAT: return TEXT( " Single + Repeat" );
case ORDER_NORMAL: return TEXT( " Normal" );
case ORDER_NORMAL_REPEAT: return TEXT( " Normal + Repeat" );
case ORDER_INVERSE: return TEXT( " Inverse" );
case ORDER_INVERSE_REPEAT: return TEXT( " Inverse + Repeat" );
case ORDER_RANDOM: return TEXT( " Random" );
default: return NULL;
}
}
/*
int Playback::Order::GetModeNameLen( int iMode )
{
switch( uMode )
{
case ORDER_SINGLE: return 7;
case ORDER_SINGLE_REPEAT: return 16;
case ORDER_NORMAL: return 7;
case ORDER_NORMAL_REPEAT: return 16;
case ORDER_INVERSE: return 8;
case ORDER_INVERSE_REPEAT: return 17;
case ORDER_RANDOM: return 7;
default: return 0;
}
}
*/
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool NextNormal( int & iCur, int iMax )
{
if( iCur >= iMax ) return false;
iCur++;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool NextNormalRepeat( int & iCur, int iMax )
{
if( iCur >= iMax )
iCur = 0;
else
iCur++;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool NextInverse( int & iCur, int iMax )
{
if( iCur <= 0 ) return false;
iCur--;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool NextInverseRepeat( int & iCur, int iMax )
{
if( iCur <= 0 )
iCur = iMax;
else
iCur--;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool NextRandom( int & iCur, int iMax )
{
if( iMax < 2 ) return false;
if( !bRandomReady )
{
srand( ( unsigned )time( NULL ) );
bRandomReady = true;
}
const int iNew = ( int )( rand() / ( float )RAND_MAX * iMax );
if( iNew != iCur )
iCur = iNew;
else
{
if( iCur >= iMax )
iCur = 0;
else
iCur++;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Order::Next( int & iCur, int iMax )
{
switch( iCurOrder )
{
case ORDER_SINGLE: return false;
case ORDER_SINGLE_REPEAT: return true;
case ORDER_NORMAL: return NextNormal( iCur, iMax );
case ORDER_NORMAL_REPEAT: return NextNormalRepeat( iCur, iMax );
case ORDER_INVERSE: return NextInverse( iCur, iMax );
case ORDER_INVERSE_REPEAT: return NextInverseRepeat( iCur, iMax );
case ORDER_RANDOM: return NextRandom( iCur, iMax );
default: return false;
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Order::Prev( int & iCur, int iMax )
{
switch( iCurOrder )
{
case ORDER_SINGLE: return false;
case ORDER_SINGLE_REPEAT: return true;
case ORDER_NORMAL: return NextInverse( iCur, iMax );
case ORDER_NORMAL_REPEAT: return NextInverseRepeat( iCur, iMax );
case ORDER_INVERSE: return NextNormal( iCur, iMax );
case ORDER_INVERSE_REPEAT: return NextNormalRepeat( iCur, iMax );
case ORDER_RANDOM: return NextRandom( iCur, iMax );
default: return false;
}
}
+380
View File
@@ -0,0 +1,380 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Usage instructions
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// =======================================================================================
// Plugins
// ---------------------------------------------------------------------------------------
// Plainamp setup > The output plugin must be manually loaded and activated the first time it's used.
// After that the ini saves OutputPluginActive___out_wave_gpl.dll=1. Input plugins are automatically
// found, loaded and activated.
// =======================================================================================
// =======================================================================================
// The ini path szIniPath
// ---------------------------------------------------------------------------------------
/* We will get problems if the program can't find the ini settings. Plugins will not be loaded,
or loadedand then unloaded before activated, or not working. */
// =======================================================================================
///////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯
#include <iostream>
//#include "Unicode.h"
//#include "Output.h"
#include <windows.h>
#include <string>
#include "Global.h" // Local
#include "Font.h"
#include "InputPlugin.h"
#include "OutputPlugin.h"
#include "VisPlugin.h"
#include "DspPlugin.h"
#include "GenPlugin.h"
#include "Main.h"
#include "Rebar.h"
#include "Playlist.h"
#include "Status.h"
#include "PluginManager.h"
#include "Prefs.h"
#include "Config.h"
#include "Emabox/Emabox.h"
#include "Console.h"
#include "PlayerExport.h" // DLL Player
/////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Declarations and definitions
// ¯¯¯¯¯¯¯¯¯¯
// -------------------------
// Keys
// ---------
#define PLUS_ALT ( FVIRTKEY | FALT )
#define PLUS_CONTROL ( FVIRTKEY | FCONTROL )
#define PLUS_CONTROL_ALT ( FVIRTKEY | FCONTROL | FALT )
#define PLUS_CONTROL_SHIFT ( FVIRTKEY | FCONTROL | FSHIFT )
#define PLUS_SHIFT ( FVIRTKEY | FSHIFT )
// -------------
HINSTANCE g_hInstance = NULL; // extern
HINSTANCE hInstance = NULL; // extern
TCHAR * szHomeDir = NULL; // extern
int iHomeDirLen = 0; // extern
TCHAR * szPluginDir = NULL; // extern
int iPluginDirLen = 0; // extern
// -------------------------
/* Read global settings from the ini file. They are read from the ini file through Config.h.
Usage: ( &where to place it, the option name, public or private, default value) */
// ---------
TCHAR szCurDir[ MAX_PATH + 1 ] = TEXT( "" );
ConfCurDir ccdCurDir( szCurDir, TEXT( "CurDir" ) );
// -------------------------
bool bWarnPluginsMissing;
ConfBool cbWarnPluginsMissing( &bWarnPluginsMissing, TEXT( "WarnPluginsMissing" ), CONF_MODE_PUBLIC, false );
bool bLoop;
ConfBool cbLoop( &bLoop, TEXT( "Loop" ), CONF_MODE_PUBLIC, false );
/////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The first function that is called by the exe
////////////////////////////////////////////////////////////////////////////////
void Player_Main(bool Console)
{
// =======================================================================================
// Set variables
//g_hInstance = hInstance;
// =======================================================================================
//printf( "DLL > main_dll() opened\n" );
if (Console) Player_Console(true);
//MessageBox(0, "main() opened", "", 0);
//printf( "main() opened\n" );
Console::Print( "\n=========================================================\n\n\n" );
//Console::Print( "DLL > Player_Main() > Begin\n" );
Console::Print( "DLL > Settings:\n", bLoop);
// =======================================================================================
// Load full config from ini file
//Conf::Init( hInstance );
Conf::Init( );
// ---------------------------------------------------------------------------------------
Console::Print( "DLL > Loop: %i\n", bLoop);
Console::Print( "DLL > WarnPluginsMissing: %i\n", bWarnPluginsMissing);
// ---------------------------------------------------------------------------------------
// =======================================================================================
// =======================================================================================
/* Get home dir. We use the TCHAR type for the dirname to insure us against foreign letters
in the dirnames */
szHomeDir = new TCHAR[ MAX_PATH + 1 ];
iHomeDirLen = GetModuleFileName( NULL, szHomeDir, MAX_PATH );
//if( !iHomeDirLen ) return 1;
// ---------------------------------------------------------------------------------------
// Walk through the pathname and look for backslashes
TCHAR * walk = szHomeDir + iHomeDirLen - 1;
while( ( walk > szHomeDir ) && ( *walk != TEXT( '\\' ) ) ) walk--;
// ---------------------------------------------------------------------------------------
walk++;
*walk = TEXT( '\0' );
iHomeDirLen = walk - szHomeDir;
// =======================================================================================
// =======================================================================================
/* Get plugins dir. Notice to change the number 8 in two places below if the dir name
is changed */
szPluginDir = new TCHAR[ MAX_PATH + 1 ];
memcpy( szPluginDir, szHomeDir, iHomeDirLen * sizeof( TCHAR ) );
memcpy( szPluginDir + iHomeDirLen, TEXT( "PluginsMusic" ), 12 * sizeof( TCHAR ) );
szPluginDir[ iHomeDirLen + 12 ] = TEXT( '\0' );
Console::Print("DLL > Plugindir: %s\n", szPluginDir);
// =======================================================================================
#ifndef NOGUI
Font::Create();
//Console::Append( TEXT( "Winmain.cpp called Font::Create()" ) );
#endif
// ---------------------------------------------------------------------------------------
// Set volume. This must probably be done after the dll is loaded.
//GlobalVolume = Playback::Volume::Get(); // Don't bother with this for now
//GlobalCurrentVolume = GlobalVolume;
//Output_SetVolume( GlobalVolume );
Console::Print("DLL > Volume: %i\n\n", GlobalVolume);
// ---------------------------------------------------------------------------------------
// =======================================================================================
// The only thing this function currently does is creating the Playlist.
// =======================================================================================
BuildMainWindow();
//addfiletoplaylist("c:\\zelda\\demo37_01.ast");
//addfiletoplaylist("c:\\zelda\\demo36_02.ast");
//Console::Append( TEXT( "Winmain.cpp called BuildMainWindow()" ) );
//Prefs::Create(); // This creates windows preferences
//Console::Append( TEXT( "Winmain.cpp called Prefs::Create()" ) );
// Find plugins
Plugin::FindAll<InputPlugin> ( szPluginDir, TEXT( "in_*.dll" ), true );
Plugin::FindAll<OutputPlugin>( szPluginDir, TEXT( "out_*.dll" ), false );
Plugin::FindAll<VisPlugin> ( szPluginDir, TEXT( "vis_*.dll" ), false );
Plugin::FindAll<DspPlugin> ( szPluginDir, TEXT( "dsp_*.dll" ), false );
Plugin::FindAll<GenPlugin> ( szPluginDir, TEXT( "gen_*.dll" ), true );
//Console::Print( "Winmain.cpp > PluginManager::Fill()\n" );
PluginManager::Fill();
//Console::Print( "Winmain.cpp > PluginManager::Fill()\n" );
// =======================================================================================
// Check plugin presence
// =======================================================================================
// =======================================================================================
// Todo: all the rest...
// ACCEL accels[] = {
// =======================================================================================
// =======================================================================================
//Playback::Play();
//play_file("C:\\opening.hps");
//play_file("C:\\Files\\Spel och spelfusk\\Console\\Gamecube\\Code\\Dolphin\\Binary\\win32\\evt_x_event_00.dsp");
//printf("Winmain.cpp called Playback.cpp:Playback::Play()\n");
// =======================================================================================
// ---- Set volume and get current location ----
// Somehow we don't have access to active_input_plugin->plugin->GetLength() from here so
// we have to call it in Playback::UpdateSeek() instead
//Sleep(1000);
//Playback::UpdateSeek();
//Output_SetVolume( 100 ); // volume is better set from the ini file
// ---------------------------------------------------------------------------------------
// =======================================================================================
// =======================================================================================
// Check the plugins
if( input_plugins.empty() )
{
Console::Print("\n *** Warning: No valid input plugins found\n\n");
}
else
{
Console::Print(" >>> These valid input plugins were found:\n");
for(int i = 0; i < input_plugins.size(); i++)
Console::Print(" %i: %s\n", (i + 1), input_plugins.at(i)->GetFilename());
Console::Print("\n");
}
// The input plugins are never activated here, they are activate for each file
if( !active_input_plugin || !active_input_plugin->plugin )
{
// Console::Print("The input plugin is not activated yet\n");
}
else
{
//const int ms_len = active_input_plugin->plugin->GetLength();
//const int ms_cur = active_input_plugin->plugin->GetOutputTime();
//Console::Print("We are at <%i of %i>\n", ms_cur, ms_len);
}
// ---------------------------------------------------------------------------------------
if( active_output_count > 0 )
{
// Show current playback progress
/*int res_temp;
for( int i = 0; i < active_output_count; i++ )
{
res_temp = active_output_plugins[ i ]->plugin->GetOutputTime();
}
Console::Print("Playback progress <%i>\n", res_temp);*/
}
else
{
Console::Print("\n *** Warning: The output plugin is not working\n\n");
}
// =======================================================================================
// =======================================================================================
// Start the timer
if(!TimerCreated && bLoop) // Only create this the first time
{
//Console::Print("Created the timer\n");
MakeTime();
TimerCreated = true;
}
// =======================================================================================
Console::Print( "\n=========================================================\n\n" );
//Console::Print( "DLL > main_dll() > End\n\n\n" );
//std::cin.get();
}
// =======================================================================================
// Should I use this?
void close()
{
printf( "The Winmain.cpp message loop was reached\n" );
// Message loop
//std::cin.get();
Playback::Stop(); // If we don't call this before we unload the dll we get a crash
printf("We are now past the message loop\n" );
//DestroyAcceleratorTable( hAccel );
// =======================================================================================
// Input
vector <InputPlugin *>::iterator iter_input = input_plugins.begin();
while( iter_input != input_plugins.end() )
{
( *iter_input )->Unload();
iter_input++;
}
// Output
vector <OutputPlugin *>::iterator iter_output = output_plugins.begin();
while( iter_output != output_plugins.end() )
{
( *iter_output )->Unload();
iter_output++;
}
// General
vector <GenPlugin *>::iterator iter_gen = gen_plugins.begin();
while( iter_gen != gen_plugins.end() )
{
( *iter_gen )->Unload();
iter_gen++;
}
// =======================================================================================
// TODO: create main::destroy
// UnregisterClass( PA_CLASSNAME, g_hInstance );
//Prefs::Destroy();
//Font::Destroy();
/*
delete [] szPluginDir;
delete [] szHomeDir;
*/
// ---------------------------------------------------------------------------------------
// We don't save any changes
//Conf::Write();
//printf("Winmain.cpp called Conf::Write(), the last function\n");
// ---------------------------------------------------------------------------------------
//std::cin.get(); // Let use see all messages
//return 0;
}
// =======================================================================================
+181
View File
@@ -0,0 +1,181 @@
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯
#include <iostream> // System
#include "Common.h" // Global common
#include "ConsoleWindow.h"
//#include "../../Common/Src/Console.h" // Local common
#include "OutputPlugin.h" // Local
#include "Playback.h"
#include "Playlist.h"
#define _DLL_PLAYER_H_
#include "PlayerExport.h" // DLL Player
//////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Declarations and definitions
// ¯¯¯¯¯¯¯¯¯¯
std::string CurrentlyPlayingFile;
int GlobalVolume = -1;
bool GlobalMute = false;
bool GlobalPause;
bool TimerCreated = false;
bool Initialized = false;
/////////////////////////////////
// -------------------------
/* We keep the file in the playlist, even though we currently only ever have one file here
at a time */
// ---------
void AddFileToPlaylist(char * a)
{
//playlist->RemoveAll();
#include "unicode.h"
const int iLen = strlen(a); // I can't do this because I don't
printf( "iLen <%i>\n", iLen );
// ---------------------------------------------------------------------------------------
// Do some string conversion
TCHAR * szKeep;
szKeep = new TCHAR[ iLen + 1 ];
ToTchar( szKeep, a, iLen );
szKeep[ iLen ] = TEXT( '\0' );
playlist->PushBack( szKeep );
// ---------------------------------------------------------------------------------------
// If we added a second file the current index = -1 so we have to change that back
playlist->SetCurIndex( 0 );
}
void Player_Play(char * FileName)
{
Console::Print("Play file <%s>\n", FileName);
// Check if the file exists
if(GetFileAttributes(FileName) == INVALID_FILE_ATTRIBUTES)
{
Console::Print("Warning: The file <%s> does not exist. Something is wrong.\n", FileName);
return;
}
Playback::Stop();
//Console::Print("Stop\n");
playlist->RemoveAll();
//Console::Print("RemoveAll\n");
AddFileToPlaylist(FileName);
//Console::Print("addfiletoplaylist\n");
// Play the file
Playback::Play();
CurrentlyPlayingFile = FileName;
// ---------------------------------------------------------------------------------------
// Set volume. This must probably be done after the dll is loaded.
//Output_SetVolume( Playback::Volume::Get() );
//Console::Print("Volume(%i)\n", Playback::Volume::Get());
// ---------------------------------------------------------------------------------------
GlobalPause = false;
}
void Player_Stop()
{
Playback::Stop();
//Console::Print("Stop\n");
playlist->RemoveAll();
CurrentlyPlayingFile = "";
GlobalPause = false;
}
void Player_Pause()
{
if (!GlobalPause)
{
Console::Print("DLL > Pause\n");
Playback::Pause();
GlobalPause = true;
}
else
{
Console::Print("DLL > UnPause from Pause\n");
Player_Unpause();
GlobalPause = false;
}
}
void Player_Unpause()
{
Console::Print("DLL > UnPause\n");
Playback::Play();
GlobalPause = false;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Declarations and definitions
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
/* About the volume: The colume is normally update for the output plugin in Output.cpp and for the
inout plugin (why?) in Playback.cpp with Playback::Volume::Set(). But I don't know how that works
so I only use GlobalVolume to keep track of the volume */
// ------------------------------
void Player_Mute(int Vol)
{
if(GlobalVolume == -1) GlobalVolume = Vol;
Console::Print("DLL > Mute <%i> <%i>\n", GlobalVolume, GlobalMute);
GlobalMute = !GlobalMute;
// Set volume
if(GlobalMute)
{
Output_SetVolume( 0 );
Console::Print("DLL > Volume <%i>\n", GlobalMute);
}
else
{
Output_SetVolume( GlobalVolume );
Console::Print("DLL > Volume <%i>\n", GlobalMute);
}
//Console::Print("Volume(%i)\n", Playback::Volume::Get());
}
///////////////////////////////////////
void Player_Volume(int Vol)
{
GlobalVolume = Vol;
Output_SetVolume( GlobalVolume );
//Console::Print("DLL > Volume <%i> <%i>\n", GlobalVolume, GlobalCurrentVolume);
}
void ShowConsole()
{
Console::Open(100, 2000, "MusicMod", true); // give room for 2000 rows
}
void Player_Console(bool Console)
{
if(Console)
ShowConsole();
else
#if defined (_WIN32)
FreeConsole();
#endif
}
+49
View File
@@ -0,0 +1,49 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯
//////////////////////////////////
// -------------------------
// DLL Player
// ---------
void MakeTime();
#ifndef _DLL_PLAYER_H_
extern int GlobalVolume;
extern int GlobalCurrentVolume;
extern bool GlobalPause;
extern bool TimerCreated;
#endif
// Dll export
#define EXPORT __declspec(dllexport)
EXPORT void Player_Main(bool Console);
EXPORT void Player_Console(bool Console);
EXPORT void Player_Play(char *);
EXPORT void Player_Stop();
EXPORT void Player_Pause();
EXPORT void Player_Unpause();
EXPORT void Player_Mute(int Vol);
EXPORT void Player_Volume(int Vol);
File diff suppressed because it is too large. Load diff
+65
View File
@@ -0,0 +1,65 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_PLAYLIST_H
#define PA_PLAYLIST_H
#include "Global.h"
#include "PlaylistControler.h"
#include "PlaylistView.h"
#define PLAINAMP_PL_REM_SEL 50004
#define PLAINAMP_PL_REM_CROP 50005
extern HWND WindowPlaylist;
extern PlaylistControler * playlist;
namespace Playlist
{
bool Create();
/*
int GetCurIndex();
int GetMaxIndex();
bool SetCurIndex( int iIndex );
*/
TCHAR * GetFilename( int iIndex );
int GetFilename( int iIndex, char * szAnsiFilename, int iChars );
int GetTitle( int iIndex, char * szAnsiTitle, int iChars );
bool DialogOpen();
bool DialogSaveAs();
bool AppendPlaylistFile( TCHAR * szFilename );
bool ExportPlaylistFile( TCHAR * szFilename );
/*
bool Append( TCHAR * szDisplay, TCHAR * szFilename );
bool Add( int iIndex, TCHAR * szDisplay, TCHAR * szFilename );
bool Clear(); // aka RemoveAll()
bool RemoveSelected();
bool Crop(); // aka RemoveUnselected
bool SelectZero();
bool SelectAll();
*/
};
#endif // PA_PLAYLIST_H
+467
View File
@@ -0,0 +1,467 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "PlaylistControler.h"
#include "Config.h"
#include "Font.h"
#include "Console.h"
bool bPlaylistFollow;
ConfBool cbPlaylistFollow( &bPlaylistFollow, TEXT( "PlaylistFollow" ), CONF_MODE_PUBLIC, true );
void PlaylistControler::MoveSelected( int iDistance )
{
if( iDistance == -1 )
{
if( ListView_GetItemState( _hView, 0, LVIS_SELECTED ) )
{
// Cannot move upwards
return;
}
}
else if( iDistance == 1 )
{
if( ListView_GetItemState( _hView, _database.GetMaxIndex(), LVIS_SELECTED ) )
{
// Cannot move downwards
return;
}
}
else
{
// More distance maybe later
return;
}
const int iFocus = ListView_GetNextItem( _hView, ( UINT )-1, LVIS_FOCUSED );
// Negative is to the top
LRESULT iBefore = 0;
LRESULT iAfter = -2; // Extra value to check after big for-loop
for( ; ; )
{
// Count
LRESULT iAfter = ListView_GetNextItem( _hView, iBefore - 1, LVNI_SELECTED );
if( iAfter == -1 ) break; // No more selections selected
LRESULT iFirst = iAfter;
// Search end of selection block
iBefore = iAfter + 1;
for( ; ; )
{
iAfter = ListView_GetNextItem( _hView, iBefore - 1, LVNI_SELECTED );
if( iAfter == iBefore )
{
// Keep searching
iBefore++;
}
else
{
// End found (iBefore is the first not selected)
const int iSelSize = iBefore - iFirst;
if( iDistance == -1 )
{
// Updwards
const int iOldIndex = iFirst - 1;
const int iNewIndex = iOldIndex + iSelSize;
TCHAR * szData = ( TCHAR * )_database.Get( iOldIndex );
_database.Erase( iOldIndex );
_database.Insert( iNewIndex, szData );
ListView_SetItemState( _hView, iOldIndex, LVIS_SELECTED, LVIS_SELECTED );
ListView_SetItemState( _hView, iNewIndex, 0, LVIS_SELECTED );
ListView_RedrawItems( _hView, iOldIndex, iNewIndex );
}
else
{
// Downwards
const int iOldIndex = iFirst + iSelSize;
const int iNewIndex = iFirst;
TCHAR * szData = ( TCHAR * )_database.Get( iOldIndex );
_database.Erase( iOldIndex );
_database.Insert( iNewIndex, szData );
ListView_SetItemState( _hView, iOldIndex, LVIS_SELECTED, LVIS_SELECTED );
ListView_SetItemState( _hView, iNewIndex, 0, LVIS_SELECTED );
ListView_RedrawItems( _hView, iNewIndex, iOldIndex );
}
iBefore++;
break;
}
}
}
if( iAfter != -2 ) return; // Nothing was selected so nothing was moved
ListView_SetItemState( _hView, iFocus + iDistance, LVIS_FOCUSED, LVIS_FOCUSED );
Refresh();
}
int PlaylistControler::GetCurIndex()
{
return _database.GetCurIndex();
}
int PlaylistControler::GetMaxIndex()
{
return _database.GetMaxIndex();
}
int PlaylistControler::GetSize()
{
return _database.GetSize();
}
void PlaylistControler::SetCurIndex( int iIndex )
{
const int iCurIndexBefore = _database.GetCurIndex();
_database.SetCurIndex( iIndex );
// ---------------------------------------------------------------------------------------
// We disable the windows management
/*
if( bPlaylistFollow )
{
ListView_SetItemState( _hView, ( UINT )-1, 0, LVIS_SELECTED | LVIS_FOCUSED );
ListView_SetItemState( _hView, iIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
}
if( iCurIndexBefore != -1 )
ListView_RedrawItems( _hView, iCurIndexBefore, iCurIndexBefore );
ListView_RedrawItems( _hView, iIndex, iIndex );
*/
// ---------------------------------------------------------------------------------------
}
// Returns <true> on digit count change
bool PlaylistControler::FixDigitsMore()
{
const int iCountAfter = _database.GetSize();
const int iDigitsBefore = _iDigits;
while( iCountAfter > _iDigitMax )
{
_iDigitMin *= 10; // 10 -> 100
_iDigitMax = _iDigitMax * 10 + 9; // 99 -> 999
_iDigits++; // 2 -> 3
}
return ( ( _iDigits != iDigitsBefore )
|| ( iCountAfter == 1 ) ); // Force update when first item is inserted
}
// Returns <true> on digit count change
bool PlaylistControler::FixDigitsLess()
{
const int iCountAfter = _database.GetSize();
const int iDigitsBefore = _iDigits;
while( ( iCountAfter < _iDigitMin ) && ( _iDigits > 1 ) )
{
_iDigitMin /= 10; // 999 -> 99
_iDigitMax /= 10; // 100 -> 10
_iDigits--; // 3 -> 2
}
return ( _iDigits != iDigitsBefore );
}
void PlaylistControler::Refresh()
{
AutosizeColumns();
const int iFirst = ListView_GetTopIndex( _hView );
const int iLast = iFirst + ListView_GetCountPerPage( _hView );
ListView_RedrawItems( _hView, iFirst, iLast );
}
PlaylistControler::PlaylistControler( HWND hView, bool bEnableZeroPadding, int * piIndexSlave )
{
_hView = hView;
_bZeroPadding = bEnableZeroPadding;
_iDigits = 1;
_iDigitMin = 1;
_iDigitMax = 9;
_database.SetCurIndexSlave( piIndexSlave );
printf("PlaylistControler::PlaylistControler was called\n");
Refresh();
// TODO clear list view here???
}
void PlaylistControler::PushBack( TCHAR * szText )
{
const int iSize = _database.GetMaxIndex();
_database.PushBack( szText );
// ---------------------------------------------------------------------------------------
// Disabled windows function
//ListView_SetItemCount( _hView, _database.GetSize() );
//if( FixDigitsMore() ) Refresh();
// ---------------------------------------------------------------------------------------
}
void PlaylistControler::Insert( int i, TCHAR * szText )
{
const int iSize = _database.GetMaxIndex();
_database.Insert( i, szText );
ListView_SetItemCount( _hView, _database.GetSize() );
if( FixDigitsMore() ) Refresh();
}
void PlaylistControler::RemoveAll()
{
_database.Clear();
// This is for the windows playlist, we don't use that
//ListView_DeleteAllItems( _hView );
if( FixDigitsLess() ) Refresh();
}
void PlaylistControler::RemoveSelected( bool bPositive )
{
SendMessage( _hView, WM_SETREDRAW, FALSE, 0 );
if( bPositive )
{
LRESULT iWalk = 0;
for( ; ; )
{
// MSDN: The specified item itself is excluded from the search.
iWalk = ListView_GetNextItem( _hView, iWalk - 1, LVNI_SELECTED );
if( iWalk != -1 )
{
_database.Erase( iWalk );
ListView_DeleteItem( _hView, iWalk );
}
else
{
break;
}
}
}
else
{
LRESULT iBefore = 0;
LRESULT iAfter = 0;
for( ; ; )
{
// MSDN: The specified item itself is excluded from the search.
iAfter = ListView_GetNextItem( _hView, iBefore - 1, LVNI_SELECTED );
if( iAfter != -1 )
{
// <iAfter> is the first selected
// so we delete all before and restart
// at the beginning
const int iDelIndex = iBefore;
for( int i = iBefore; i < iAfter; i++ )
{
_database.Erase( iDelIndex );
ListView_DeleteItem( _hView, iDelIndex );
}
iBefore++; // Exclude the one we found selected right before
}
else
{
if( iBefore == 0 )
{
// All selected
_database.Clear();
ListView_DeleteAllItems( _hView );
}
else
{
const int iSize = _database.GetSize();
const int iDelIndex = iBefore;
for( int i = iBefore; i < iSize; i++ )
{
_database.Erase( iDelIndex );
ListView_DeleteItem( _hView, iDelIndex );
}
}
break;
}
}
}
bool bRefresh = FixDigitsLess();
SendMessage( _hView, WM_SETREDRAW, TRUE, 0 );
if( bRefresh ) Refresh();
}
void PlaylistControler::SelectAll( bool bPositive )
{
ListView_SetItemState( _hView, ( UINT )-1, bPositive ? LVIS_SELECTED : 0, LVIS_SELECTED );
}
void PlaylistControler::SelectInvert()
{
SendMessage( _hView, WM_SETREDRAW, FALSE, 0 );
const int iOneTooMuch = _database.GetSize();
for( int i = 0; i < iOneTooMuch; i++ )
{
ListView_SetItemState(
_hView,
i,
( ListView_GetItemState( _hView, i, LVIS_SELECTED ) == LVIS_SELECTED )
? 0
: LVIS_SELECTED,
LVIS_SELECTED
);
}
SendMessage( _hView, WM_SETREDRAW, TRUE, 0 );
}
const TCHAR * PlaylistControler::Get( int i )
{
Console::Append( TEXT("We are in PlaylistControler::Get()") );
return _database.Get( i );
}
void PlaylistControler::Fill( LVITEM & request )
{
if( ( request.mask & LVIF_TEXT ) == 0 ) return;
if( request.iSubItem )
{
// Text
_sntprintf( request.pszText, request.cchTextMax, TEXT( "%s" ), _database.Get( request.iItem ) );
}
else
{
// Number
if( _bZeroPadding )
{
TCHAR szFormat[ 6 ];
_stprintf( szFormat, TEXT( "%%0%dd" ), _iDigits );
_sntprintf( request.pszText, request.cchTextMax, szFormat, request.iItem + 1 );
}
else
{
_sntprintf( request.pszText, request.cchTextMax, TEXT( "%d" ), request.iItem + 1 );
}
}
}
void PlaylistControler::EnableZeroPadding( bool bActive )
{
if( bActive == _bZeroPadding ) return;
LVCOLUMN col;
memset( &col, 0, sizeof( LVCOLUMN ) );
col.mask = LVCF_FMT;
if( bActive )
{
// TODO recalculation yes/no?
/*
int iSize = _database.GetSize();
if( iSize != 0 )
{
int iDigits = 0;
while( iSize > 0 )
{
iSize /= 10;
iDigits++;
}
_iDigits = iSize;
_iDigitMin = 1;
_iDigitMax = 9;
while( iSize-- > 0 )
{
_iDigitMin *= 10;
_iDigitMax = _iDigitMax * 10 + 9;
}
}
else
{
_iDigits = 1;
_iDigitMin = 1;
_iDigitMax = 9;
}
*/
col.fmt = LVCFMT_LEFT;
ListView_SetColumn( _hView, 0, &col );
Refresh();
}
else
{
col.fmt = LVCFMT_RIGHT;
ListView_SetColumn( _hView, 0, &col );
Refresh();
}
_bZeroPadding = bActive;
}
void PlaylistControler::AutosizeColumns()
{
RECT r;
if( !GetClientRect( _hView, &r ) ) return;
if( _bZeroPadding )
{
ListView_SetColumnWidth( _hView, 0, LVSCW_AUTOSIZE );
const int iWidth = ListView_GetColumnWidth( _hView, 0 );
ListView_SetColumnWidth( _hView, 1, r.right - r.left - iWidth );
}
else
{
HDC hdc = GetDC( _hView );
const HFONT hOldFont = ( HFONT )SelectObject( hdc, Font::Get() );
SIZE size;
BOOL res = GetTextExtentPoint32( hdc, TEXT( "0" ), 1, &size );
SelectObject( hdc, hOldFont );
ReleaseDC( _hView, hdc );
const int iWidth = res ? ( int )( size.cx * ( _iDigits + 0.25f ) ) : 120;
ListView_SetColumnWidth( _hView, 0, iWidth );
ListView_SetColumnWidth( _hView, 1, r.right - r.left - iWidth );
}
}
void PlaylistControler::Resize( HWND hParent )
{
/*
RECT rc;
GetClientRect( hParent, &rc );
MoveWindow( _hView, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE );
*/
AutosizeColumns();
}
+65
View File
@@ -0,0 +1,65 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PLAYLIST_CONTROLER_H
#define PLAYLIST_CONTROLER_H 1
#include <tchar.h>
#include <windows.h>
#include <commctrl.h>
#include "PlaylistModel.h"
// TODO: column width update on scrollbar show/hide
class PlaylistControler
{
PlaylistModel _database;
HWND _hView;
bool _bZeroPadding;
int _iDigits; // 3
int _iDigitMin; // 100
int _iDigitMax; // 999
private:
bool FixDigitsMore();
bool FixDigitsLess();
void Refresh();
void AutosizeColumns();
public:
PlaylistControler( HWND hView, bool bEnableZeroPadding, int * piIndexSlave );
void MoveSelected( int iDistance );
int GetCurIndex();
int GetMaxIndex();
int GetSize();
void SetCurIndex( int iIndex );
void PushBack( TCHAR * szText );
void Insert( int i, TCHAR * szText );
void RemoveAll();
void RemoveSelected( bool bPositive );
void SelectAll( bool bPositive );
void SelectInvert();
const TCHAR * Get( int i );
void Fill( LVITEM & request );
void EnableZeroPadding( bool bActive );
void Resize( HWND hParent );
};
#endif // PLAYLIST_CONTROLER_H
+122
View File
@@ -0,0 +1,122 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
// =======================================================================================
#include "Console.h"
#include "Global.h"
// =======================================================================================
#ifndef PLAYLIST_MODEL_H
#define PLAYLIST_MODEL_H 1
#include <windows.h>
#include <tchar.h>
#include <vector>
using namespace std;
class PlaylistModel
{
vector<TCHAR *> _database;
int _iCurIndex;
int * _piCurIndex;
public:
PlaylistModel()
{
_piCurIndex = &_iCurIndex;
}
PlaylistModel( int * piIndexSlave )
{
_piCurIndex = piIndexSlave;
}
void SetCurIndexSlave( int * piIndexSlave )
{
// *piIndexSlave = *_piCurIndex;
_piCurIndex = piIndexSlave;
}
// =======================================================================================
// This is where the _database is populated
// =======================================================================================
void PushBack( TCHAR * szText )
{
Console::Append( TEXT( "PlaylistModel.h:_database.PushBack() was called " ) );
_database.push_back( szText ); // this is a <vector> API call
}
void Insert( int i, TCHAR * szText )
{
Console::Append( TEXT( "PlaylistModel.h:_database.Insert() was called " ) );
if( i <= *_piCurIndex ) ( *_piCurIndex )++;
_database.insert( _database.begin() + i, szText );
}
void Erase( int i )
{
if( i < *_piCurIndex ) ( *_piCurIndex )--;
_database.erase( _database.begin() + i );
}
const TCHAR * Get( int i )
{
//Console::Append( TEXT( "PlaylistModel.h:_database.Get() was called " ) );
if( 0 > i || i >= ( int )_database.size() )
{
static const TCHAR * szError = TEXT( "INDEX OUT OF RANGE" );
return szError;
}
return _database[ i ];
}
void Clear()
{
_database.clear();
*_piCurIndex = -1;
}
int GetMaxIndex()
{
return _database.size() - 1;
}
int GetCurIndex()
{
return *_piCurIndex;
}
void SetCurIndex( int iIndex )
{
if( 0 > iIndex || iIndex >= ( int )_database.size() )
{
Console::Print("SetCurIndex > Return");
return;
}
*_piCurIndex = iIndex;
}
int GetSize()
{
return _database.size();
}
};
#endif // PLAYLIST_MODEL_H
+782
View File
@@ -0,0 +1,782 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
// =======================================================================================
#include "Playlist.h"
#include "Main.h"
#include "Status.h"
#include "Rebar.h"
#include "Playback.h"
#include "Config.h"
#include "Util.h"
WNDPROC WndprocPlaylistBackup = NULL;
LRESULT CALLBACK WndprocPlaylist( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
// =======================================================================================
// =======================================================================================
// This gives the values from the ini file.
// ConfBool = class
PlaylistControler * playlist = NULL; // extern
bool bPlaylistEntryNumberZeroPadding;
ConfBool cbPlaylistEntryNumberZeroPadding( &bPlaylistEntryNumberZeroPadding, TEXT( "PlaylistEntryNumberZeroPadding" ), CONF_MODE_PUBLIC, true );
int iCurPlaylistPosition;
ConfInt ciCurPlaylistPosition( &iCurPlaylistPosition, TEXT( "CurPlaylistPosition" ), CONF_MODE_INTERNAL, -1 );
bool bInfinitePlaylist;
ConfBool cbInfinitePlaylist( &bInfinitePlaylist, TEXT( "InfinitePlaylist" ), CONF_MODE_PUBLIC, false );
// =======================================================================================
// =======================================================================================
void PlaylistView::Create()
{
#ifndef NOGUI
RECT ClientMain;
GetClientRect( WindowMain, &ClientMain );
const int iClientHeight = ClientMain.bottom - ClientMain.top;
const int iClientWidth = ClientMain.right - ClientMain.left;
const int iPlaylistHeight = iClientHeight - iRebarHeight - iStatusHeight;
//LoadCommonControls();
DWORD dwStyle;
// HWND WindowPlaylist;
BOOL bSuccess = TRUE;
dwStyle = WS_TABSTOP |
WS_CHILD |
WS_BORDER |
WS_VISIBLE |
LVS_AUTOARRANGE | // TODO
LVS_REPORT |
LVS_OWNERDATA |
LVS_NOCOLUMNHEADER ;
WindowPlaylist = CreateWindowEx( WS_EX_CLIENTEDGE, // ex style
WC_LISTVIEW, // class name - defined in commctrl.h
TEXT( "" ), // dummy text
dwStyle, // style
0,
iRebarHeight, // + -2,
iClientWidth,
iPlaylistHeight,
WindowMain, // parent
NULL, // ID
g_hInstance, // instance
NULL); // no extra data
if(!WindowPlaylist) return; // TODO
// This calls PlaylistControler::PlaylistControler()
playlist = new PlaylistControler( WindowPlaylist, bPlaylistEntryNumberZeroPadding, &iCurPlaylistPosition );
#else
HWND WindowPlaylist = NULL;
playlist = new PlaylistControler( WindowPlaylist, bPlaylistEntryNumberZeroPadding, &iCurPlaylistPosition );
#endif
// Exchange window procedure
//WndprocPlaylistBackup = ( WNDPROC )GetWindowLong( WindowPlaylist, GWL_WNDPROC );
//if( WndprocPlaylistBackup != NULL )
//{
// SetWindowLong( WindowPlaylist, GWL_WNDPROC, ( LONG )WndprocPlaylist );
//}
//ListView_SetExtendedListViewStyle( WindowPlaylist, LVS_EX_FULLROWSELECT ); // | LVS_EX_GRIDLINES );
//playlist->Resize( WindowMain );
/*
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/listview/structures/lvcolumn.asp
*
* Remarks:
* If a column is added to a list-view control with index 0 (the leftmost column)
* and with LVCFMT_RIGHT or LVCFMT_CENTER specified, the text is not right-aligned
* or centered. The text in the index 0 column is left-aligned. Therefore if you
* keep inserting columns with index 0, the text in all columns are left-aligned.
* If you want the first column to be right-aligned or centered you can make a dummy
* column, then insert one or more columns with index 1 or higher and specify the
* alignment you require. Finally delete the dummy column.
*/
//LV_COLUMN lvColumn;
//memset( &lvColumn, 0, sizeof( LV_COLUMN ) );
//lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
//
//// Number column (with dummy hack)
//lvColumn.fmt = LVCFMT_LEFT;
//lvColumn.cx = 0;
//lvColumn.pszText = TEXT( "" );
//ListView_InsertColumn( WindowPlaylist, 0, &lvColumn );
//lvColumn.fmt = LVCFMT_RIGHT;
//lvColumn.cx = 120;
//lvColumn.pszText = TEXT( "" );
//ListView_InsertColumn( WindowPlaylist, 1, &lvColumn );
//ListView_DeleteColumn( WindowPlaylist, 0 );
// Entry
//lvColumn.fmt = LVCFMT_LEFT;
//lvColumn.cx = 120;
//lvColumn.pszText = TEXT( "Filename" );
//ListView_InsertColumn(WindowPlaylist, 1, &lvColumn);
/*
stupid test code
SCROLLINFO scrollinfo;
ZeroMemory( &scrollinfo, sizeof( SCROLLINFO ) );
scrollinfo.cbSize = sizeof( SCROLLINFO );
scrollinfo.fMask = 0; // SIF_DISABLENOSCROLL;
if( !GetScrollInfo( WindowPlaylist, SB_VERT, &scrollinfo ) )
{
MessageBox( 0, "ERROR", "", 0 );
}
else
{
MessageBox( 0, "OKAY", "", 0 );
scrollinfo.fMask = SIF_DISABLENOSCROLL;
SetScrollInfo( WindowPlaylist, SB_VERT, &scrollinfo, TRUE );
}
if( !ShowScrollBar( WindowPlaylist, SB_VERT, TRUE ) )
{
MessageBox( 0, "ERROR ShowScrollBar", "", 0 );
}
SCROLLBARINFO scrollbarinfo;
scrollbarinfo.cbSize = sizeof( SCROLLBARINFO );
if( !GetScrollBarInfo( WindowPlaylist, OBJID_VSCROLL, &scrollbarinfo ) )
{
MessageBox( 0, "ERROR GetScrollBarInfo", "", 0 );
}
*/
}
// Dragging
static int iItemHeight = 15;
static int iDragStartY = 0;
static bool bDragging = false;
// Liquid selection
static bool bLiquidSelecting = false;
static int iLastTouched = -1;
// Liquid or range selection
static int iSelAnchor = -1;
LRESULT CALLBACK WndprocPlaylist( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
/*
* Click, click and click
*
* [Alt] [Ctrl] [Shift] Action
* -------+---------+---------+-----------------------
* X | X | X |
* X | X | |
* X | | X |
* X | | |
* | X | X | Range selection
* | X | | Toggle selection
* | | X | Range selection
* | | | Single selection
*
*
* Click, hold and move
*
* [Alt] [Ctrl] [Shift] Action
* -------+---------+---------+-----------------------
* X | X | X | Selection move
* X | X | | Selection move
* X | | X | Selection move
* X | | | Selection move
* | X | X |
* | X | |
* | | X |
* | | | Liquid selection
*/
static bool bCapturing = true;
switch( message )
{
/*
case WM_CAPTURECHANGED:
if( bCapturing && ( GetCapture() != WindowPlaylist ) )
{
MessageBox( 0, TEXT( "Capture stolen" ), TEXT( "" ), 0 );
}
break;
*/
case WM_MOUSEMOVE:
if( bLiquidSelecting )
{
LVHITTESTINFO hittest;
memset( &hittest, 0, sizeof( LVHITTESTINFO ) );
hittest.pt.x = LOWORD( lp );
hittest.pt.y = HIWORD( lp );
const int iIndex = ( int )ListView_HitTest( WindowPlaylist, &hittest );
if( iIndex == -1 ) return 0;
if( iIndex == iLastTouched ) return 0;
// Note: Update this as early as possible!
// We cannot be sure this code is
// not called two or three times at the
// same time without losing much speed
// but this at least lowers the chance
const int iLastTouchedBackup = iLastTouched;
iLastTouched = iIndex;
const bool bControl = ( ( GetKeyState( VK_CONTROL ) & 0x8000 ) != 0 );
ListView_SetItemState( WindowPlaylist, ( UINT )-1, 0, LVIS_FOCUSED );
ListView_SetItemState( WindowPlaylist, iIndex, LVIS_FOCUSED, LVIS_FOCUSED );
// Below anchor?
if( iIndex > iSelAnchor )
{
if( iIndex > iLastTouchedBackup )
{
// iSelAnchor
// ..
// iLastTouchedBackup
// ..
// >> iIndex <<
if( iLastTouchedBackup > iSelAnchor )
{
// Select downwards
for( int i = iLastTouchedBackup + 1; i <= iIndex; i++ )
ListView_SetItemState( WindowPlaylist, i, LVIS_SELECTED, LVIS_SELECTED );
}
// iLastTouchedBackup
// ..
// iSelAnchor
// ..
// >> iIndex <<
else
{
// Unselect downwards
for( int i = iLastTouchedBackup; i < iSelAnchor; i++ )
ListView_SetItemState( WindowPlaylist, i, 0, LVIS_SELECTED );
// Select downwards
for( int i = iSelAnchor + 1; i <= iIndex; i++ )
ListView_SetItemState( WindowPlaylist, i, LVIS_SELECTED, LVIS_SELECTED );
}
}
else // iIndex < iLastTouchedBackup
{
// iSelAnchor
// ..
// >> iIndex <<
// ..
// iLastTouchedBackup
// Unselect upwards
for( int i = iLastTouchedBackup; i > iIndex; i-- )
ListView_SetItemState( WindowPlaylist, i, 0, LVIS_SELECTED );
}
}
// Above anchor?
else if( iIndex < iSelAnchor )
{
if( iIndex < iLastTouchedBackup )
{
// >> iIndex <<
// ..
// iSelAnchor
// ..
// iLastTouchedBackup
if( iIndex < iLastTouchedBackup )
{
// Unselect upwards
for( int i = iLastTouchedBackup; i > iSelAnchor; i-- )
ListView_SetItemState( WindowPlaylist, i, 0, LVIS_SELECTED );
// Select upwards
for( int i = iSelAnchor - 1; i >= iIndex; i-- )
ListView_SetItemState( WindowPlaylist, i, LVIS_SELECTED, LVIS_SELECTED );
}
// >> iIndex <<
// ..
// iLastTouchedBackup
// ..
// iSelAnchor
else // iIndex < iLastTouchedBackup
{
// Select upwards
for( int i = iLastTouchedBackup - 1; i >= iIndex; i-- )
ListView_SetItemState( WindowPlaylist, i, LVIS_SELECTED, LVIS_SELECTED );
}
}
else // iIndex > iLastTouchedBackup
{
// iLastTouchedBackup
// ..
// >> iIndex <<
// ..
// iSelAnchor
// Unselect downwards
for( int i = iLastTouchedBackup; i < iIndex; i++ )
ListView_SetItemState( WindowPlaylist, i, 0, LVIS_SELECTED );
}
}
// At anchor
else // iIndex == iSelAnchor
{
if( iIndex < iLastTouchedBackup )
{
// iSelAnchor / >> iIndex <<
// ..
// iLastTouchedBackup
// Unselect upwards
for( int i = iLastTouchedBackup; i > iSelAnchor; i-- )
{
ListView_SetItemState( WindowPlaylist, i, 0, LVIS_SELECTED );
}
}
else // iIndex > iLastTouchedBackup
{
// iLastTouchedBackup
// ..
// iSelAnchor / >> iIndex <<
// Unselect downwards
for( int i = iLastTouchedBackup; i < iSelAnchor; i++ )
ListView_SetItemState( WindowPlaylist, i, 0, LVIS_SELECTED );
}
}
}
else if( bDragging )
{
static bool bMoveLock = false;
if( bMoveLock ) return 0;
bMoveLock = true;
const int y = HIWORD( lp );
const int diff = y - iDragStartY;
if( abs( diff ) > iItemHeight / 2 )
{
iDragStartY += ( ( diff > 0 ) ? iItemHeight : -iItemHeight );
playlist->MoveSelected( ( diff > 0 ) ? +1 : -1 );
}
bMoveLock = false;
}
return 0;
case WM_LBUTTONDOWN:
{
static int iLastClicked = -1;
static bool bLastClickNoneOrShift = true;
SetFocus( hwnd ); // TODO monitor focus loss
LVHITTESTINFO hittest;
memset( &hittest, 0, sizeof( LVHITTESTINFO ) );
GetCursorPos( &hittest.pt );
ScreenToClient( hwnd, &hittest.pt );
const int iIndex = ( int )ListView_HitTest( WindowPlaylist, &hittest );
if( iIndex == -1 ) return 0;
const bool bShift = ( ( GetKeyState( VK_SHIFT ) & 0x8000 ) != 0 );
const bool bControl = ( ( GetKeyState( VK_CONTROL ) & 0x8000 ) != 0 );
const bool bAlt = ( ( GetKeyState( VK_MENU ) & 0x8000 ) != 0 );
// [Shift] or [Shift]+[Ctrl]?
if( bShift )
{
if( bAlt ) return 0;
// Last click usable as selection anchor?
if( !bLastClickNoneOrShift )
{
// Treat as normal click
iSelAnchor = iIndex;
iLastClicked = iIndex;
ListView_SetItemState( WindowPlaylist, ( UINT )-1, 0, LVIS_SELECTED | LVIS_FOCUSED );
ListView_SetItemState( WindowPlaylist, iIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
bLiquidSelecting = true;
bLastClickNoneOrShift = true;
return 0;
}
if( iIndex != iLastClicked )
{
// Below anchor?
if( iIndex > iSelAnchor )
{
// Below last click?
if( iIndex > iLastClicked )
{
// Other side of anchor?
if( iLastClicked < iSelAnchor )
{
// Unselect downwards
for( int i = iLastClicked; i < iSelAnchor; i++ )
ListView_SetItemState( WindowPlaylist, i, 0, LVIS_SELECTED );
// Select downwards
for( int i = iSelAnchor; i <= iIndex; i++ )
ListView_SetItemState( WindowPlaylist, i, LVIS_SELECTED, LVIS_SELECTED );
}
// Same side of anchor?
else
{
// Select downwards
for( int i = iLastClicked + 1; i <= iIndex; i++ )
ListView_SetItemState( WindowPlaylist, i, LVIS_SELECTED, LVIS_SELECTED );
}
}
// Above last click?
else // iIndex < iLastClicked
{
// Unselect upwards
for( int i = iLastClicked; i > iIndex; i-- )
ListView_SetItemState( WindowPlaylist, i, 0, LVIS_SELECTED );
}
}
// Above anchor?
else if( iIndex < iSelAnchor )
{
// Above last clicked?
if( iIndex < iLastClicked )
{
// Other side of anchor?
if( iLastClicked > iSelAnchor )
{
// Unselect upwards
for( int i = iLastClicked; i > iSelAnchor; i-- )
ListView_SetItemState( WindowPlaylist, i, 0, LVIS_SELECTED );
// Select upwards
for( int i = iSelAnchor; i >= iIndex; i-- )
ListView_SetItemState( WindowPlaylist, i, LVIS_SELECTED, LVIS_SELECTED );
}
// Same side of anchor?
else
{
// Select upwards
for( int i = iLastClicked - 1; i >= iIndex; i-- )
ListView_SetItemState( WindowPlaylist, i, LVIS_SELECTED, LVIS_SELECTED );
}
}
// Below last clicked?
else // iIndex > iLastClicked
{
// Unselect downwards
for( int i = iLastClicked; i < iIndex; i++ )
ListView_SetItemState( WindowPlaylist, i, 0, LVIS_SELECTED );
}
}
// At anchor
else // iIndex == iSelAnchor
{
if( iLastClicked < iSelAnchor )
{
// Unselect downwards
for( int i = iLastClicked; i < iIndex; i++ )
ListView_SetItemState( WindowPlaylist, i, 0, LVIS_SELECTED );
}
else if( iLastClicked > iSelAnchor )
{
// Unselect upwards
for( int i = iLastClicked; i > iIndex; i-- )
ListView_SetItemState( WindowPlaylist, i, 0, LVIS_SELECTED );
}
}
iLastClicked = iIndex;
ListView_SetItemState( WindowPlaylist, ( UINT )-1, 0, LVIS_FOCUSED );
ListView_SetItemState( WindowPlaylist, iIndex, LVIS_FOCUSED, LVIS_FOCUSED );
}
bLastClickNoneOrShift = true;
}
// [Ctrl]?
else if( bControl )
{
if( bAlt ) return 0;
iLastTouched = iIndex;
// Toggle selection
const bool bSelected = ( ListView_GetItemState( WindowPlaylist, iIndex, LVIS_SELECTED ) == LVIS_SELECTED );
ListView_SetItemState( WindowPlaylist, iIndex, bSelected ? 0 : LVIS_SELECTED, LVIS_SELECTED );
ListView_SetItemState( WindowPlaylist, ( UINT )-1, 0, LVIS_FOCUSED );
ListView_SetItemState( WindowPlaylist, iIndex, LVIS_FOCUSED, LVIS_FOCUSED );
bLastClickNoneOrShift = false;
}
// [Alt]?
else if( bAlt )
{
// Update item height
RECT rc;
GetClientRect( WindowPlaylist, &rc );
const int iItemsPerPage = ListView_GetCountPerPage( WindowPlaylist );
iItemHeight = ( rc.bottom - rc.top ) / iItemsPerPage;
iDragStartY = hittest.pt.y;
bDragging = true;
bCapturing = true;
SetCapture( WindowPlaylist );
}
// No modifiers?
else
{
iSelAnchor = iIndex;
iLastClicked = iIndex;
ListView_SetItemState( WindowPlaylist, ( UINT )-1, 0, LVIS_SELECTED | LVIS_FOCUSED );
ListView_SetItemState( WindowPlaylist, iIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
bLiquidSelecting = true;
bLastClickNoneOrShift = true;
bCapturing = true;
SetCapture( WindowPlaylist );
}
}
return 0;
case WM_LBUTTONUP:
bLiquidSelecting = false;
bDragging = false;
bCapturing = false;
ReleaseCapture();
return 0;
case WM_SYSKEYDOWN:
switch( wp ) // [Alt]+[...]
{
case VK_UP:
playlist->MoveSelected( -1 );
break;
case VK_DOWN:
playlist->MoveSelected( +1 );
break;
}
break;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
case WM_CHAR:
case WM_KEYUP:
// SMALL LETTERS!!!!!!
switch( wp )
{
case 'z':
case 'y':
case 'x':
case 'c':
case 'v':
case 'b':
case 'l':
return 0;
}
break;
case WM_KEYDOWN:
{
const bool bShift = ( ( GetKeyState( VK_SHIFT ) & 0x8000 ) != 0 );
const bool bControl = ( ( GetKeyState( VK_CONTROL ) & 0x8000 ) != 0 );
// Note: [Alt] goes to WM_SYSKEYDOWN instead
// const bool bAlt = ( ( GetKeyState( VK_MENU ) & 0x8000 ) != 0 );
switch( wp )
{
case VK_LEFT:
if( bShift || bControl ) return 0;
SendMessage( WindowMain, WM_COMMAND, WINAMP_REW5S, 0 );
return 0;
case VK_RIGHT:
if( bShift || bControl ) return 0;
SendMessage( WindowMain, WM_COMMAND, WINAMP_FFWD5S, 0 );
return 0;
case VK_UP:
if( bInfinitePlaylist )
{
// First item has focus?
if( ListView_GetNextItem( WindowPlaylist, ( UINT )-1, LVNI_FOCUSED ) != 0 ) break;
if( bControl && !bShift )
{
// Move caret only
ListView_SetItemState( WindowPlaylist, ( UINT )-1, 0, LVNI_FOCUSED );
ListView_SetItemState( WindowPlaylist, playlist->GetMaxIndex(), LVNI_FOCUSED, LVNI_FOCUSED );
return 0;
}
else
{
// Move Caret and selection
ListView_SetItemState( WindowPlaylist, ( UINT )-1, 0, LVNI_FOCUSED );
ListView_SetItemState( WindowPlaylist, playlist->GetMaxIndex() - 1, LVNI_FOCUSED, LVNI_FOCUSED );
wp = VK_DOWN;
}
}
break;
case VK_DOWN:
if( bInfinitePlaylist )
{
// Last item has focus?
if( ListView_GetNextItem( WindowPlaylist, playlist->GetMaxIndex() - 1, LVNI_FOCUSED ) == -1 ) break;
if( bControl && !bShift )
{
// Move caret only
ListView_SetItemState( WindowPlaylist, ( UINT )-1, 0, LVNI_FOCUSED );
ListView_SetItemState( WindowPlaylist, 0, LVNI_FOCUSED, LVNI_FOCUSED );
return 0;
}
else
{
// Workaround
ListView_SetItemState( WindowPlaylist, ( UINT )-1, 0, LVNI_FOCUSED );
ListView_SetItemState( WindowPlaylist, 1, LVNI_FOCUSED, LVNI_FOCUSED );
wp = VK_UP;
}
}
break;
case VK_DELETE:
{
if( bShift ) break;
if( bControl )
playlist->RemoveSelected( false );
else
playlist->RemoveSelected( true );
break;
}
case VK_RETURN:
playlist->SetCurIndex( ListView_GetNextItem( WindowPlaylist, ( UINT )-1, LVIS_FOCUSED ) );
SendMessage( WindowMain, WM_COMMAND, WINAMP_BUTTON2, 0 );
return 0;
case 'Y':
case 'Z':
if( bShift || bControl ) return 0;
SendMessage( WindowMain, WM_COMMAND, WINAMP_BUTTON1, 0 );
return 0;
case 'X':
if( bShift || bControl ) return 0;
SendMessage( WindowMain, WM_COMMAND, WINAMP_BUTTON2, 0 );
return 0;
case 'C':
if( bShift || bControl ) return 0;
SendMessage( WindowMain, WM_COMMAND, WINAMP_BUTTON3, 0 );
return 0;
case 'V':
// Todo modifiers pressed? -> fadeout/...
if( bShift || bControl ) return 0;
SendMessage( WindowMain, WM_COMMAND, WINAMP_BUTTON4, 0 );
return 0;
case 'B':
if( bShift || bControl ) return 0;
SendMessage( WindowMain, WM_COMMAND, WINAMP_BUTTON5, 0 );
return 0;
/*
case 'J':
if( bShift || bControl ) return 0;
SendMessage( WindowMain, WM_COMMAND, WINAMP_JUMPFILE, 0 );
return 0;
*/
case 'L':
if( bControl ) return 0;
SendMessage( WindowMain, WM_COMMAND, bShift ? WINAMP_FILE_DIR : WINAMP_FILE_PLAY, 0 );
return 0;
}
break;
}
case WM_LBUTTONDBLCLK:
// iCurIndex = Playlist_MouseToIndex();
LVHITTESTINFO hittest;
memset( &hittest, 0, sizeof( LVHITTESTINFO ) );
GetCursorPos( &hittest.pt );
ScreenToClient( hwnd, &hittest.pt );
const int iIndex = ( int )ListView_HitTest( WindowPlaylist, &hittest );
if( iIndex == -1 ) break;
playlist->SetCurIndex( iIndex );
Playback::Play();
Playback::UpdateSeek();
break;
}
return CallWindowProc( WndprocPlaylistBackup, hwnd, message, wp, lp );
}
+27
View File
@@ -0,0 +1,27 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PLAYLIST_VIEW_H
#define PLAYLIST_VIEW_H 1
#include "Global.h"
namespace PlaylistView
{
void Create();
};
#endif // PLAYLIST_VIEW_H
+63
View File
@@ -0,0 +1,63 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Plugin.h"
#include "InputPlugin.h"
#include "OutputPlugin.h"
#include "VisPlugin.h"
#include "DspPlugin.h"
#include "GenPlugin.h"
vector<Plugin *> plugins; // extern
int Plugin::iWndprocHookCounter = 0;
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
Plugin::Plugin( TCHAR * szDllpath )
{
hDLL = NULL;
szName = NULL;
iNameLen = 0;
iFullpathLen = ( int )_tcslen( szDllpath );
szFullpath = new TCHAR[ iFullpathLen + 1 ];
memcpy( szFullpath, szDllpath, iFullpathLen * sizeof( TCHAR ) );
szFullpath[ iFullpathLen ] = TEXT( '\0' );
TCHAR * walk = szFullpath + iFullpathLen - 1;
while( ( *walk != TEXT( '\\') ) && ( walk >= szFullpath ) ) walk--;
if( *walk == TEXT( '\\') ) walk++;
szFilename = walk;
iFilenameLen = iFullpathLen - ( walk - szFullpath );
_tcslwr( szFilename );
plugins.push_back( this );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
Plugin::~Plugin()
{
if( szFullpath ) delete [] szFullpath;
if( szName ) delete [] szName;
}
+142
View File
@@ -0,0 +1,142 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_PLUGIN_H
#define PA_PLUGIN_H
#include "Global.h"
#include <vector>
using namespace std;
class Plugin;
extern vector<Plugin *> plugins;
enum PluginType
{
PLUGIN_TYPE_INPUT,
PLUGIN_TYPE_OUTPUT,
PLUGIN_TYPE_VIS,
PLUGIN_TYPE_DSP,
PLUGIN_TYPE_GEN
};
////////////////////////////////////////////////////////////////////////////////
/// Winamp plugin wrapper
////////////////////////////////////////////////////////////////////////////////
class Plugin
{
public:
Plugin( TCHAR * szDllpath );
~Plugin();
virtual bool Load() = 0;
virtual bool Unload() = 0;
virtual TCHAR * GetTypeString() = 0;
virtual int GetTypeStringLen() = 0;
virtual PluginType GetType() = 0;
// void AllowUnload( bool bAllow ) { bAllowUnload = bAllow; }
inline bool IsLoaded() { return ( hDLL != NULL ); }
virtual bool IsActive() = 0;
inline TCHAR * GetFullpath() { return szFullpath; }
// inline int GetFullpathLen() { return iFilenameLen; }
inline TCHAR * GetFilename() { return szFilename; }
inline int GetFilenameLen() { return iFilenameLen; }
inline TCHAR * GetName() { return szName; }
inline int GetNameLen() { return iNameLen; }
template< class PluginKind >
static bool FindAll( TCHAR * szPath, TCHAR * szPattern, bool bKeepLoaded );
protected:
HINSTANCE hDLL; ///< Library handle
TCHAR * szName; ///< Name
int iNameLen; ///< Length of name (in characters)
BOOL iHookerIndex; ///< Window hook index (0..HC-1). Only last can be unloaded
WNDPROC WndprocBackup; ///< Window procedure backup. Is restored when unloading. Only valid for <iHookerIndex != -1>
static int iWndprocHookCounter; ///< Number of window hooks (=HC)
private:
TCHAR * szFullpath; ///< Full path e.g. "C:\test.dll"
TCHAR * szFilename; ///< Filename e.g. "test.dll"
int iFullpathLen; ///< Length of full path (in characters)
int iFilenameLen; ///< Length of filename (in characters)
};
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
template< class PluginKind >
bool Plugin::FindAll( TCHAR * szPath, TCHAR * szPattern, bool bKeepLoaded )
{
const int uPathLen = ( int )_tcslen( szPath );
const int uPatternLen = ( int )_tcslen( szPattern );
TCHAR * szFullPattern = new TCHAR[ uPathLen + 1 + uPatternLen + 1 ];
memcpy( szFullPattern, szPath, uPathLen * sizeof( TCHAR ) );
szFullPattern[ uPathLen ] = TEXT( '\\' );
memcpy( szFullPattern + uPathLen + 1, szPattern, uPatternLen * sizeof( TCHAR ) );
szFullPattern[ uPathLen + 1 + uPatternLen ] = TEXT( '\0' );
WIN32_FIND_DATA fd;
HANDLE hFind = FindFirstFile( szFullPattern, &fd );
if( hFind == INVALID_HANDLE_VALUE )
{
delete [] szFullPattern;
return false;
}
do
{
const int iFilenameLen = ( int )_tcslen( fd.cFileName );
TCHAR * szFullpath = new TCHAR[ uPathLen + 1 + iFilenameLen + 1 ];
memcpy( szFullpath, szPath, uPathLen * sizeof( TCHAR ) );
szFullpath[ uPathLen ] = TEXT( '\\' );
memcpy( szFullpath + uPathLen + 1, fd.cFileName, iFilenameLen * sizeof( TCHAR ) );
szFullpath[ uPathLen + 1 + iFilenameLen ] = TEXT( '\0' );
////////////////////////////////////////////////////////////////////////////////
new PluginKind( szFullpath, bKeepLoaded );
////////////////////////////////////////////////////////////////////////////////
delete [] szFullpath;
}
while( FindNextFile( hFind, &fd ) );
FindClose( hFind );
delete [] szFullPattern;
return true;
}
#endif // PA_PLUGIN_H
File diff suppressed because it is too large. Load diff
+42
View File
@@ -0,0 +1,42 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_PLUGIN_MANAGER_H
#define PA_PLUGIN_MANAGER_H
#include "Global.h"
#include "Plugin.h"
extern HWND WindowManager;
void UpdatePluginStatus( Plugin * plugin, bool bLoaded, bool bActive );
namespace PluginManager
{
bool Build();
bool Fill();
bool Destroy();
bool Popup();
};
#endif // PA_PLUGIN_MANAGER_H
+565
View File
@@ -0,0 +1,565 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Prefs.h"
#include "Util.h"
#include "Font.h"
#include "Console.h"
#include <map>
using namespace std;
#define CLASSNAME_PREFS TEXT( "CLASSNAME_PREFS" )
#define TITLE_PREFS TEXT( "Preferences" )
#define PAGE_WIDTH 409
#define PAGE_HEIGHT 400
#define GAP_LEFT 4
#define GAP_RIGHT 5
#define GAP_TOP 4
#define GAP_BOTTOM 5
#define SPLITTER_WIDTH 6
#define SPLITTER_HEIGHT 6
#define BOTTOM_SPACE 36
#define BUTTON_WIDTH 80
#define PREFS_WIDTH 606
#define PREFS_HEIGHT ( GAP_TOP + PAGE_HEIGHT + BOTTOM_SPACE )
struct PrefRecCompare
{
bool operator()( const prefsDlgRec * a, const prefsDlgRec * b ) const
{
if( a->hInst < b->hInst ) return true;
if( a->dlgID < b->dlgID ) return true;
return strcmp( a->name, b->name ) < 0;
}
};
map<prefsDlgRec *, HTREEITEM, PrefRecCompare> rec_to_item;
struct AllWeNeed
{
prefsDlgRec * PageData;
HWND hwnd;
};
HWND WindowPrefs = NULL;
HWND WindowPage = NULL;
HWND WindowTree = NULL;
HWND ButtonClose = NULL;
HTREEITEM root = NULL;
HWND hCurrentPage = NULL;
// bool bKeepFocus = false;
LRESULT CALLBACK WndprocPrefs( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
LRESULT CALLBACK WndprocTree( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
WNDPROC WndprocTreeBackup = NULL;
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Prefs::Create()
{
if( WindowPrefs ) return false;
// Register class
WNDCLASS wc = {
0, // UINT style
WndprocPrefs, // WNDPROC lpfnWndProc
0, // int cbClsExtra
0, // int cbWndExtra
g_hInstance, // HINSTANCE hInstance
NULL, // HICON hIcon
LoadCursor( NULL, IDC_ARROW ), // HCURSOR hCursor
( HBRUSH )COLOR_WINDOW, // HBRUSH hbrBackground
NULL, // LPCTSTR lpszMenuName
CLASSNAME_PREFS // LPCTSTR lpszClassName
};
if( !RegisterClass( &wc ) ) return false;
const int cxScreen = GetSystemMetrics( SM_CXFULLSCREEN );
const int cyScreen = GetSystemMetrics( SM_CYFULLSCREEN );
// Create window
WindowPrefs = CreateWindowEx(
WS_EX_WINDOWEDGE | // DWORD dwExStyle
WS_EX_TOOLWINDOW, //
CLASSNAME_PREFS, // LPCTSTR lpClassName
TITLE_PREFS, // LPCTSTR lpWindowName
WS_OVERLAPPED | // DWORD dwStyle
// WS_VISIBLE | //
WS_CLIPCHILDREN | //
WS_SYSMENU, //
( cxScreen - PREFS_WIDTH ) / 2, // int x
( cyScreen - PREFS_HEIGHT ) / 2, // int y
PREFS_WIDTH, // int nWidth
PREFS_HEIGHT, // int nHeight
NULL, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
if( !WindowPrefs )
{
UnregisterClass( CLASSNAME_PREFS, g_hInstance );
return false;
}
RECT r;
GetClientRect( WindowPrefs, &r );
////////////////////////////////////////////////////////////////////////////////
const int iWidth = PREFS_WIDTH * 2 - r.right;
const int iHeight = PREFS_HEIGHT * 2 - r.bottom;
SetWindowPos(
WindowPrefs,
NULL,
( cxScreen - iWidth ) / 2,
( cyScreen - iHeight ) / 2,
iWidth,
iHeight,
SWP_NOZORDER
);
GetClientRect( WindowPrefs, &r );
////////////////////////////////////////////////////////////////////////////////
LoadCommonControls();
const int iTreeWidth = ( r.right - r.left ) - PAGE_WIDTH - GAP_LEFT - GAP_RIGHT - SPLITTER_WIDTH;
WindowTree = CreateWindowEx(
WS_EX_CLIENTEDGE, // DWORD dwExStyle
WC_TREEVIEW, // LPCTSTR lpClassName
NULL, // LPCTSTR lpWindowName
WS_VSCROLL | // DWORD dwStyle
WS_VISIBLE | //
WS_CHILD | //
WS_TABSTOP | //
TVS_HASLINES | //
TVS_LINESATROOT | //
TVS_HASBUTTONS | //
TVS_SHOWSELALWAYS | //
TVS_DISABLEDRAGDROP | //
TVS_NONEVENHEIGHT, //
GAP_LEFT, // int x
GAP_TOP, // int y
iTreeWidth, // int nWidth
PAGE_HEIGHT, // int nHeight
WindowPrefs, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
if( !WindowTree )
{
; //...
}
Font::Apply( WindowTree );
// Exchange window procedure
WndprocTreeBackup = ( WNDPROC )GetWindowLong( WindowTree, GWL_WNDPROC );
if( WndprocTreeBackup != NULL )
{
SetWindowLong( WindowTree, GWL_WNDPROC, ( LONG )WndprocTree );
}
const int iPageLeft = GAP_LEFT + iTreeWidth + SPLITTER_WIDTH;
WindowPage = CreateWindowEx(
0, // DWORD dwExStyle
TEXT( "Static" ), // LPCTSTR lpClassName
TEXT( "Nothing to see here" ), // LPCTSTR lpWindowName
WS_TABSTOP | // DWORD dwStyle
WS_VISIBLE | //
WS_CHILD | //
SS_CENTER | //
SS_CENTERIMAGE, //
iPageLeft, // int x
GAP_TOP, // int y
PAGE_WIDTH, // int nWidth
PAGE_HEIGHT, // int nHeight
WindowPrefs, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
if( !WindowPage )
{
; //...
}
Font::Apply( WindowPage );
const int iButtonLeft = ( r.right - r.left ) - GAP_RIGHT - BUTTON_WIDTH - 1;
const int iButtonTop = ( r.bottom - r.top ) - BOTTOM_SPACE + SPLITTER_HEIGHT;
ButtonClose = CreateWindowEx(
0, // DWORD dwExStyle
TEXT( "Button" ), // LPCTSTR lpClassName
TEXT( "Close" ), // LPCTSTR lpWindowName
WS_TABSTOP | // DWORD dwStyle
WS_VISIBLE | //
WS_CHILD | //
BS_PUSHBUTTON | //
BS_TEXT | //
BS_VCENTER, //
iButtonLeft, // int x
iButtonTop, // int y
BUTTON_WIDTH, // int nWidth
BOTTOM_SPACE - SPLITTER_HEIGHT - GAP_BOTTOM, // int nHeight
WindowPrefs, // HWND hWndParent
NULL, // HMENU hMenu
g_hInstance, // HINSTANCE hInstance
NULL // LPVOID lpParam
);
Font::Apply( ButtonClose );
AllWeNeed * awn_root = new AllWeNeed;
// memset( &awn_root->PageData, 0, sizeof( prefsDlgRec ) );
awn_root->PageData = NULL;
awn_root->hwnd = NULL;
TV_INSERTSTRUCT tvi = {
root, // HTREEITEM hParent
TVI_SORT, // HTREEITEM hInsertAfter
{
TVIF_PARAM | TVIF_STATE | TVIF_TEXT, // UINT mask
NULL, // HTREEITEM hItem
TVIS_EXPANDED | TVIS_SELECTED, // UINT state
0, // UINT stateMask
TEXT( "General" ), // LPSTR pszText
8, // int cchTextMax
0, // int iImage
0, // int iSelectedImage
0, // int cChildren
( LPARAM )awn_root // LPARAM lParam
}
};
root = TreeView_InsertItem( WindowTree, &tvi );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Prefs::Destroy()
{
if( !WindowPrefs ) return false;
DestroyWindow( WindowPrefs );
UnregisterClass( CLASSNAME_PREFS, g_hInstance );
WindowPrefs = NULL;
DestroyWindow( WindowTree );
WindowTree = NULL;
DestroyWindow( WindowPage );
WindowPage = NULL;
DestroyWindow( ButtonClose );
ButtonClose = NULL;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Prefs_Show( HTREEITEM item )
{
if( !WindowPrefs ) return false;
// Select and load associated page
TreeView_SelectItem( WindowTree, item );
if( !IsWindowVisible( WindowPrefs ) )
{
ShowWindow( WindowPrefs, SW_SHOW );
}
SetActiveWindow( WindowPrefs );
SetFocus( WindowTree );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Prefs::Show()
{
return Prefs_Show( root );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Prefs::Show( prefsDlgRec * PageData )
{
map<prefsDlgRec *, HTREEITEM, PrefRecCompare>::iterator iter = rec_to_item.find( PageData );
if( iter != rec_to_item.end() )
{
return Prefs_Show( iter->second );
}
else
{
return Prefs_Show( root );
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Prefs::AddPage( prefsDlgRec * PageData )
{
// TODO unicode!
if( !WindowPrefs ) return false;
// Backup
char * NameBackup = new char[ strlen( PageData->name ) + 1 ];
strcpy( NameBackup, PageData->name );
prefsDlgRec * PageDataBackup = new prefsDlgRec;
memcpy( PageDataBackup, PageData, sizeof( prefsDlgRec ) );
PageDataBackup->name = NameBackup;
AllWeNeed * awn = new AllWeNeed;
awn->PageData = PageDataBackup;
awn->hwnd = NULL;
TV_INSERTSTRUCT tvi = {
root, // HTREEITEM hParent
TVI_SORT, // HTREEITEM hInsertAfter
{ //
TVIF_PARAM | TVIF_STATE | TVIF_TEXT, // UINT mask
NULL, // HTREEITEM hItem
TVIS_EXPANDED | TVIS_SELECTED, // UINT state
0, // UINT stateMask
PageDataBackup->name, // LPSTR pszText
( int )strlen( PageDataBackup->name ) + 1, // int cchTextMax
0, // int iImage
0, // int iSelectedImage
0, // int cChildren
( LPARAM )awn // LPARAM lParam
}
};
HTREEITEM new_item = TreeView_InsertItem( WindowTree, &tvi );
TreeView_Expand( WindowTree, root, TVE_EXPAND );
rec_to_item.insert( pair<prefsDlgRec *, HTREEITEM>( PageDataBackup, new_item ) );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndprocPrefs( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
switch( message )
{
case WM_NOTIFY:
{
NMHDR * nmhdr = ( NMHDR * )lp;
if( ( nmhdr->hwndFrom == WindowTree ) && ( nmhdr->code == TVN_SELCHANGING ) )
{
NMTREEVIEW * nmtv = ( NMTREEVIEW * )lp;
TVITEM * OldPage = &nmtv->itemOld;
TVITEM * NewPage = &nmtv->itemNew;
// Destroy old window
AllWeNeed * old_awn = ( AllWeNeed * )OldPage->lParam;
if( old_awn && old_awn->hwnd && IsWindow( old_awn->hwnd ) )
{
DestroyWindow( old_awn->hwnd );
old_awn->hwnd = NULL;
}
// Create new window
AllWeNeed * new_awn = ( AllWeNeed * )NewPage->lParam;
if( new_awn )
{
prefsDlgRec * PageData = new_awn->PageData;
if( PageData && PageData->hInst ) // root has NULL here
{
if( !PageData->proc )
{
MessageBox( 0, TEXT( "proc NULL" ), TEXT( "" ), 0 );
PageData->proc = ( void * )WndprocPrefs;
}
/*
RECT r;
GetWindowRect( WindowPage, &r );
const int iWidth = r.right - r.left;
const int iHeight = r.bottom - r.top;
POINT p = { r.left, r.top };
ScreenToClient( WindowPrefs, &p );
MoveWindow( WindowPage, p.x, p.y, iWidth - 10, iHeight - 10, FALSE );
*/
// bKeepFocus = true;
HWND hPage = CreateDialog(
PageData->hInst, // HINSTANCE hInstance,
( LPCTSTR )PageData->dlgID, // LPCTSTR lpTemplate,
WindowPage, // HWND hWndParent,
( DLGPROC )PageData->proc // DLGPROC lpDialogFunc
);
new_awn->hwnd = hPage;
// MoveWindow( WindowPage, p.x, p.y, iWidth, iHeight, FALSE );
ShowWindow( hPage, SW_SHOW );
UpdateWindow( hPage );
SetFocus( WindowTree );
/*
SetActiveWindow( hPage );
SetActiveWindow( hwnd );
*/
hCurrentPage = hPage;
// bKeepFocus = false;
}
/*
else
{
MessageBox( 0, TEXT( "hInst NULL" ), TEXT( "" ), 0 );
}
*/
}
else
{
MessageBox( 0, TEXT( "awn NULL" ), TEXT( "" ), 0 );
}
}
break;
}
case WM_COMMAND:
switch( HIWORD( wp ) )
{
case BN_CLICKED:
if( ( HWND )lp == ButtonClose )
{
PostMessage( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
}
break;
}
break;
case WM_SYSCOMMAND:
if( ( wp & 0xFFF0 ) == SC_CLOSE )
{
ShowWindow( hwnd, SW_HIDE );
// Destroy current page so the settings are saved
// (currently be selecting the empty page
TreeView_SelectItem( WindowTree, root );
/*
if( hCurrentPage && IsWindow( hCurrentPage ) )
{
DestroyWindow( hCurrentPage );
hCurrentPage = NULL;
}
*/
return 0;
}
break;
case WM_KEYDOWN:
switch( wp )
{
case VK_ESCAPE:
PostMessage( WindowPrefs, WM_SYSCOMMAND, SC_CLOSE, 0 );
break;
}
break;
/*
case WM_KILLFOCUS:
if( bKeepFocus )
{
return 1;
}
break;
*/
}
return DefWindowProc( hwnd, message, wp, lp );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndprocTree( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
switch( message )
{
case WM_KEYDOWN:
switch( wp )
{
case VK_ESCAPE:
PostMessage( WindowPrefs, WM_SYSCOMMAND, SC_CLOSE, 0 );
break;
}
break;
}
return CallWindowProc( WndprocTreeBackup, hwnd, message, wp, lp );
}
+36
View File
@@ -0,0 +1,36 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_PREFS_H
#define PA_PREFS_H
#include "Global.h"
#include "Winamp/wa_ipc.h"
namespace Prefs
{
bool Create();
bool Destroy();
bool Show();
bool Show( prefsDlgRec * PageData );
bool AddPage( prefsDlgRec * PageData );
};
#endif // PA_PREFS_H
File diff suppressed because it is too large. Load diff
+40
View File
@@ -0,0 +1,40 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_TOOLBAR_H
#define PA_TOOLBAR_H
#include "Global.h"
extern HWND WindowRebar;
extern HWND WindowOrder;
extern HWND WindowEq;
extern HWND WindowSeek;
extern HWND WindowVis;
extern int iRebarHeight;
namespace Toolbar
{
bool Create();
};
#endif // PA_TOOLBAR_H
Binary file not shown.

After

Width:  |  Height:  |  Size: 734 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.
+17
View File
@@ -0,0 +1,17 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by resrc1.rc
//
#define IDB_BITMAP1 102
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
+131
View File
@@ -0,0 +1,131 @@
// Microsoft Visual C++ generated resource script.
//
#include "resrc1.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
//#include "resource.h"
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Neutral resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
#ifdef _WIN32
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON "Plainamp.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,2,3,1
PRODUCTVERSION 0,2,3,1
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "CompanyName", "Hartwork Project (http://www.hartwork.org)"
VALUE "FileDescription", "Plainamp"
VALUE "FileVersion", "0, 2, 3, 1"
VALUE "InternalName", "Plainamp"
VALUE "LegalCopyright", "Copyright (C) 2005 Sebastian Pipping"
VALUE "ProductName", "Plainamp"
VALUE "ProductVersion", "0, 2, 3, 1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_BITMAP1 BITMAP "Buttons.bmp"
#endif // Neutral resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// German (Germany) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
#ifdef _WIN32
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resrc1.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""resource.h""\r\n"
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // German (Germany) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
+80
View File
@@ -0,0 +1,80 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Status.h"
#include "Main.h"
#include "Util.h"
#include "GlobalVersion.h"
int iStatusHeight = 40; // extern
HWND WindowStatus = NULL; // extern
const TCHAR * const szStatusDefault = TEXT( " " ) PLAINAMP_LONG_TITLE;
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool BuildMainStatus()
{
LoadCommonControls();
WindowStatus = CreateWindowEx(
0,
STATUSCLASSNAME,
szStatusDefault,
WS_CHILD |
WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
WindowMain,
NULL,
g_hInstance,
NULL
);
if( !WindowStatus ) return false;
RECT r = { 0, 0, 0, 0 };
GetWindowRect( WindowStatus, &r );
iStatusHeight = r.bottom - r.top;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool StatusUpdate( TCHAR * szText )
{
if( !WindowStatus ) return false;
SetWindowText( WindowStatus, szText );
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void StatusReset()
{
if( !WindowStatus ) return;
SetWindowText( WindowStatus, szStatusDefault );
}
+33
View File
@@ -0,0 +1,33 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_STATUS_H
#define PA_STATUS_H
#include "Global.h"
extern int iStatusHeight;
extern HWND WindowStatus;
bool BuildMainStatus();
bool StatusUpdate( TCHAR * szText );
void StatusReset();
#endif // PA_STATUS_H
+126
View File
@@ -0,0 +1,126 @@
// ================================================================================================
// File description
// ----------------
/* In the GUI build there is a timer that is initiated with SetTimer() that will setup a timer that
calls the lpTimerFunc function pointer as long as your program is running a message loop. If it
doesn't run one, like in a console application (the NOGUI build), you'll have to use a different
kind of timer API, like timeSetEvent() or CreateThreadPoolTimer(). These timers use a different
thread to make the callback so be careful to properly lock and synchronize. */
// ================================================================================================
// ================================================================================================
// Library requirements
// ----------------
// This program needs winmm.lib. There's no simpler or better way to make a timer withouth it.
// ================================================================================================
// ================================================================================================
// Includes
// ----------------
#include <iostream>
//using namespace std;
#include <windows.h>
#include <mmsystem.h>
#include "Global.h"
#include "PlayerExport.h"
#include "InputPlugin.h"
// ================================================================================================
////////////////////////////////////////////////////////////////////////////////////////////
// Declarations and definitions
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void MakeTime();
int g_Stop = 0;
extern std::string CurrentlyPlayingFile;
extern bool GlobalPause;
///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// Manage restart when playback for a file has reached the end of the file
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
#ifdef _M_X64
void CALLBACK Update()
#else
void CALLBACK Update(unsigned int,unsigned int,unsigned long,unsigned long,unsigned long)
#endif
{
//Console::Print("DLL > Update() > Begin (%i)\n", active_input_plugin);
// --------------------------------
// Manage restart when playback for a file has reached the end of the file
// --------------
// Check if the input plugin is activated
if(!active_input_plugin || !active_input_plugin->plugin)
{
//Console::Print("The input plugin is not activated yet\n");
}
else
{
const int ms_len = active_input_plugin->plugin->GetLength();
const int ms_cur = active_input_plugin->plugin->GetOutputTime();
// Get the current playback progress
float progress;
if(ms_len > 0)
progress = (float)ms_cur / ms_len;
else
progress = 0;
if ( progress > 0.7 ) // Only show this if we are getting close to the end, for bugtesting
// basically
{
//Console::Print("Playback progress <%i of %i>\n", ms_cur, ms_len);
}
// Because cur never go all the way to len we can't use a == comparison. Insted of this
// we could also check if the location is the same as right before.
if(ms_cur > ms_len - 1000 && !GlobalPause) // avoid restarting in cases where we just pressed pause
{
Console::Print("Restart <%s>\n", CurrentlyPlayingFile.c_str());
Player_Play((char *)CurrentlyPlayingFile.c_str());
}
}
// --------------
//Console::Print("Make new time\n");
MakeTime(); // Make a new one
}
void MakeTime()
{
timeSetEvent(
2000, // Interval in ms
0,
#ifdef _M_X64
(LPTIMECALLBACK) Update, // The function
#else
Update,
#endif
0,
0);
}
///////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// Start the timer
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
int MainTimer()
{
MakeTime();
//while( g_Stop == 0 )
//{
// cout << ".";
//}
//Console::Print("MakeTime\n");
return 0;
}
///////////////////////////
+77
View File
@@ -0,0 +1,77 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Unicode.h"
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ToAnsi( char * szDest, wchar_t * szSource, int iLen )
{
char * const szBytesource = ( char * )szSource;
for( int i = 0; i < iLen; i++ )
{
szDest[ i ] = szBytesource[ 2 * i + 1 ];
}
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
/*
void ToUnicode( wchar_t * szDest, char * szSource, int iLen )
{
for( int i = 0; i < iLen; i++ )
{
szDest[ i ] = ( wchar_t )szSource[ i ];
}
}
*/
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ToTchar( TCHAR * szDest, wchar_t * szSource, int iLen )
{
#ifdef PA_UNICODE
memcpy( szDest, szSource, 2 * iLen );
#else
char * const stByteSource = ( TCHAR * )szSource;
for( int i = 0; i < iLen; i++ )
{
szDest[ i ] = stByteSource[ 2 * i + 1 ];
}
#endif
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void ToTchar( TCHAR * szDest, char * szSource, int iLen )
{
#ifdef PA_UNICODE
for( int i = 0; i < iLen; i++ )
{
szDest[ i ] = szSource[ 2 * i + 1 ];
}
#else
memcpy( szDest, szSource, iLen );
#endif
}
+29
View File
@@ -0,0 +1,29 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_UNICODE_H
#define PA_UNICODE_H
#include "Global.h"
void ToAnsi( char * szDest, wchar_t * szSource, int iLen );
// void ToUnicode( wchar_t * szDest, char * szSource, int iLen )
void ToTchar( TCHAR * szDest, wchar_t * szSource, int iLen );
void ToTchar( TCHAR * szDest, char * szSource, int iLen );
#endif // PA_UNICODE_H
+48
View File
@@ -0,0 +1,48 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Util.h"
#ifndef ICC_STANDARD_CLASSES
# define ICC_STANDARD_CLASSES 0x00004000
#endif
bool bLoaded = false;
bool bAvailable = false;
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool LoadCommonControls()
{
if( bLoaded ) return bAvailable;
INITCOMMONCONTROLSEX icce = {
sizeof( INITCOMMONCONTROLSEX ),
ICC_BAR_CLASSES | // Statusbar, trackbar, toolbar
ICC_COOL_CLASSES | // Rebar
ICC_LISTVIEW_CLASSES | // Listview
ICC_STANDARD_CLASSES | //
ICC_TREEVIEW_CLASSES // Treeview
};
bLoaded = true;
bAvailable = ( InitCommonControlsEx( &icce ) == TRUE );
return bAvailable;
}
+26
View File
@@ -0,0 +1,26 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_UTIL_H
#define PA_UTIL_H
#include "Global.h"
bool LoadCommonControls();
#endif // PA_UTIL_H
+303
View File
@@ -0,0 +1,303 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "VisCache.h"
#include "Console.h"
#include "malloc.h"
unsigned char * SpecCacheLeft;
unsigned char * SpecCacheRight;
unsigned char * WaveCacheLeft;
unsigned char * WaveCacheRight;
int iWritePos;
int iWriteOffset; // == iWritePos * 576
int iVisLatency;
int iDataFps;
int iCacheLen;
bool bReady = false;
int iReadTimeMs = 0;
int iWriteTimeMs = 0;
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache_Resize( int iLatency, int iFps )
{
// if( !bReady ) return;
const int iNewCacheLen = ( iFps * iLatency ) / 1000 + 1;
/*
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "RESIZE ( %i * %i ) / 1000 + 1 === %i" ), iFps, iLatency, iNewCacheLen );
Console::Append( szBuffer );
*/
const int iByteNewCacheLen = iNewCacheLen * 576;
if( !iCacheLen )
{
// First time
SpecCacheLeft = ( unsigned char * )malloc( iByteNewCacheLen );
// memset( SpecCacheLeft, 0, iByteNewCacheLen );
SpecCacheRight = ( unsigned char * )malloc( iByteNewCacheLen );
// memset( SpecCacheRight, 0, iByteNewCacheLen );
WaveCacheLeft = ( unsigned char * )malloc( iByteNewCacheLen );
// memset( WaveCacheLeft, 0, iByteNewCacheLen );
WaveCacheRight = ( unsigned char * )malloc( iByteNewCacheLen );
// memset( WaveCacheRight, 0, iByteNewCacheLen );
}
else if( iNewCacheLen > iCacheLen )
{
// Grow
const int iByteCacheLen = iCacheLen * 576;
const int iByteClearLen = ( iNewCacheLen - iCacheLen ) * 576;
SpecCacheLeft = ( unsigned char * )realloc( SpecCacheLeft, iByteNewCacheLen );
// memset( SpecCacheLeft + iByteCacheLen, 0, iByteClearLen );
SpecCacheRight = ( unsigned char * )realloc( SpecCacheRight, iByteNewCacheLen );
// memset( SpecCacheRight + iByteCacheLen, 0, iByteClearLen );
WaveCacheLeft = ( unsigned char * )realloc( WaveCacheLeft, iByteNewCacheLen );
// memset( WaveCacheLeft + iByteCacheLen, 0, iByteClearLen );
WaveCacheRight = ( unsigned char * )realloc( WaveCacheRight, iByteNewCacheLen );
// memset( WaveCacheRight + iByteCacheLen, 0, iByteClearLen );
}
iCacheLen = iNewCacheLen;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::Create()
{
if( bReady ) return;
iWritePos = 0;
iWriteOffset = 0;
iVisLatency = 50;
iDataFps = 40;
iCacheLen = 0;
bReady = true;
VisCache_Resize( iVisLatency, iDataFps );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::Destroy()
{
if( !bReady ) return;
if( SpecCacheLeft ) free( SpecCacheLeft );
if( SpecCacheRight ) free( SpecCacheRight );
if( WaveCacheLeft ) free( WaveCacheLeft );
if( WaveCacheRight ) free( WaveCacheRight );
bReady = false;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::EnsureLatency( int iLatency )
{
if( !bReady ) return;
if( iLatency <= iVisLatency ) return;
VisCache_Resize(
iLatency,
iDataFps
);
iVisLatency = iLatency;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::EnsureDataFps( int iFps )
{
if( !bReady ) return;
if( iFps <= iDataFps ) return;
VisCache_Resize(
iVisLatency,
iFps
);
iDataFps = iFps;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::Clean()
{
if( !bReady ) return;
const int iByteCacheLen = iCacheLen * 576;
memset( SpecCacheLeft, 0, iByteCacheLen );
memset( SpecCacheRight, 0, iByteCacheLen );
memset( WaveCacheLeft, 0, iByteCacheLen );
memset( WaveCacheRight, 0, iByteCacheLen );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::SetReadTime( int ms )
{
iReadTimeMs = ms;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::SetWriteTime( int ms )
{
iWriteTimeMs = ms;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int VisCache::LatencyToOffset( int iLatency )
{
int iFrame = iWritePos - 1 - ( ( iWriteTimeMs - iReadTimeMs - iLatency ) * iDataFps ) / 1000;
if( iFrame < 0 ) iFrame += iCacheLen;
return iFrame * 576;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::NextFrame()
{
iWritePos++;
if( iWritePos >= iCacheLen ) iWritePos = 0;
iWriteOffset = iWritePos * 576;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::PutSpecLeft( unsigned char * data )
{
if( !bReady ) return;
memcpy( SpecCacheLeft + iWriteOffset, data, 576 );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::PutSpecRight( unsigned char * data )
{
if( !bReady ) return;
memcpy( SpecCacheRight + iWriteOffset, data, 576 );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::PutWaveLeft( unsigned char * data )
{
if( !bReady ) return;
memcpy( WaveCacheLeft + iWriteOffset, data, 576 );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::PutWaveRight( unsigned char * data )
{
if( !bReady ) return;
memcpy( WaveCacheRight + iWriteOffset, data, 576 );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::GetSpecLeft( unsigned char * dest, int iOffset )
{
if( !bReady ) return;
memcpy( dest, SpecCacheLeft + iOffset, 576 );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::GetSpecRight( unsigned char * dest, int iOffset )
{
if( !bReady ) return;
memcpy( dest, SpecCacheRight + iOffset, 576 );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::GetWaveLeft( unsigned char * dest, int iOffset )
{
if( !bReady ) return;
memcpy( dest, WaveCacheLeft + iOffset, 576 );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void VisCache::GetWaveRight( unsigned char * dest, int iOffset )
{
if( !bReady ) return;
memcpy( dest, WaveCacheRight + iOffset, 576 );
}
+50
View File
@@ -0,0 +1,50 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_VIS_CACHE_H
#define PA_VIS_CACHE_H
#include "Global.h"
namespace VisCache
{
void Create();
void Destroy();
void EnsureLatency( int iLatency ); // TODO
void EnsureDataFps( int iFps ); // TODO
void Clean();
void SetReadTime( int ms );
void SetWriteTime( int ms );
int LatencyToOffset( int iLatency );
void NextFrame();
void PutSpecLeft( unsigned char * data );
void PutSpecRight( unsigned char * data );
void PutWaveLeft( unsigned char * data );
void PutWaveRight( unsigned char * data );
void GetSpecLeft( unsigned char * dest, int iOffset );
void GetSpecRight( unsigned char * dest, int iOffset );
void GetWaveLeft( unsigned char * dest, int iOffset );
void GetWaveRight( unsigned char * dest, int iOffset );
};
#endif // PA_VIS_CACHE_H
+358
View File
@@ -0,0 +1,358 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "VisModule.h"
#include "Console.h"
#include "Unicode.h"
#include "Playback.h"
#include "VisCache.h"
#include "PluginManager.h"
#include <process.h>
VisModule ** active_vis_mods = NULL; // extern
int active_vis_count = 0; // extern
/*
BOOL CALLBACK EnumThreadWndProc( HWND hwnd, LPARAM lp )
{
// MessageBox( 0, "EnumThreadWndProc", "", 0 );
DestroyWindow( hwnd );
}
*/
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
void PlugThread( PVOID pvoid )
{
// TODO: cleanup!!!
Console::Append( TEXT( "Visualization thread born" ) );
Console::Append( " " );
VisModule * mod = ( VisModule * )pvoid;
if( !mod ) return;
if( mod->mod->Init( mod->mod ) != 0 ) return;
VisCache::Create();
////////////////////////////////////////////////////////////////////////////////
VisLock.Enter();
////////////////////////////////////////////////////////////////////////////////
active_vis_count++;
////////////////////////////////////////////////////////////////////////////////
VisLock.Leave();
////////////////////////////////////////////////////////////////////////////////
bool bKeepItGoing = true;
bool bQuitCalled = false;
int iLast = GetTickCount();
// Message loop
MSG msg;
msg.message = WM_QUIT + 1; // Must be != WM_QUIT
do
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if( msg.message == WM_QUIT )
{
////////////////////////////////////////////////////////////////////////////////
// Stop
if( !bQuitCalled )
{
mod->mod->Quit( mod->mod );
bQuitCalled = true;
}
////////////////////////////////////////////////////////////////////////////////
break;
}
TranslateMessage( &msg );
DispatchMessage( &msg );
if( msg.message == WM_CLOSE || ( ( msg.message == WM_SYSCOMMAND ) && ( msg.wParam == SC_CLOSE ) ) )
{
////////////////////////////////////////////////////////////////////////////////
// Stop
if( !bQuitCalled )
{
mod->mod->Quit( mod->mod );
bQuitCalled = true;
}
////////////////////////////////////////////////////////////////////////////////
}
}
if( bKeepItGoing )
{
// Variant A
const int iNow = GetTickCount();
if( iNow - iLast > mod->mod->delayMs )
{
if( Playback::IsPlaying() )
{
if( mod->bAllowRender )
{
mod->bAllowRender = false;
const int iOffset = VisCache::LatencyToOffset( mod->mod->latencyMs );
switch( mod->mod->spectrumNch )
{
case 2:
VisCache::GetSpecRight( mod->mod->spectrumData[ 1 ], iOffset );
case 1:
VisCache::GetSpecLeft( mod->mod->spectrumData[ 0 ], iOffset );
}
switch( mod->mod->waveformNch )
{
case 2:
VisCache::GetWaveRight( mod->mod->waveformData[ 1 ], iOffset );
case 1:
VisCache::GetWaveLeft( mod->mod->waveformData[ 0 ], iOffset );
}
if( mod->mod->Render( mod->mod ) != 0 )
{
////////////////////////////////////////////////////////////////////////////////
// Stop
if( !bQuitCalled )
{
// TODO: milkdrop doesn#t save window position
// when quit using manual plugin stop
mod->mod->Quit( mod->mod );
bQuitCalled = true;
}
////////////////////////////////////////////////////////////////////////////////
/*
// Destroy all windows belonging to this thread
// This will lead to WM_QUIT automatically
EnumThreadWindows( GetCurrentThreadId(), EnumThreadWndProc, 0 );
bKeepItGoing = false;
*/
}
iLast = iNow;
}
}
else
{
if( mod->mod->Render( mod->mod ) != 0 )
{
////////////////////////////////////////////////////////////////////////////////
// Stop
if( !bQuitCalled )
{
mod->mod->Quit( mod->mod );
bQuitCalled = true;
}
////////////////////////////////////////////////////////////////////////////////
/*
// Destroy all windows belonging to this thread
// This will lead to WM_QUIT automatically
EnumThreadWindows( GetCurrentThreadId(), EnumThreadWndProc, 0 );
bKeepItGoing = false;
*/
}
iLast = iNow;
}
}
////////////////////////////////////////////////////////////////////////////////
bool bVisLockLeft = false;
VisLock.Enter();
////////////////////////////////////////////////////////////////////////////////
if( mod->bShouldQuit )
{
////////////////////////////////////////////////////////////////////////////////
VisLock.Leave();
bVisLockLeft = true;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Stop
if( !bQuitCalled )
{
mod->mod->Quit( mod->mod );
bQuitCalled = true;
}
////////////////////////////////////////////////////////////////////////////////
/*
// Destroy all windows belonging to this thread
// This will lead to WM_QUIT automatically
EnumThreadWindows( GetCurrentThreadId(), EnumThreadWndProc, 0 );
bKeepItGoing = false;
*/
}
////////////////////////////////////////////////////////////////////////////////
if( !bVisLockLeft )
{
VisLock.Leave();
}
////////////////////////////////////////////////////////////////////////////////
}
Sleep( 1 );
}
while( msg.message != WM_QUIT );
mod->bShouldQuit = false;
////////////////////////////////////////////////////////////////////////////////
VisLock.Enter();
if( ( active_vis_count > 1 ) && ( mod->iArrayIndex < active_vis_count - 1 ) )
{
active_vis_mods[ mod->iArrayIndex ] = active_vis_mods[ active_vis_count - 1 ];
active_vis_mods[ mod->iArrayIndex ]->iArrayIndex = mod->iArrayIndex;
}
active_vis_count--;
VisLock.Leave();
////////////////////////////////////////////////////////////////////////////////
mod->iArrayIndex = -1;
/*
// Stop
mod->mod->Quit( mod->mod );
*/
////////////////////////////////////////////////////////////////////////////////
VisLock.Enter();
mod->bActive = false;
VisLock.Leave();
////////////////////////////////////////////////////////////////////////////////
UpdatePluginStatus( mod->plugin, true, mod->plugin->IsActive() );
Console::Append( TEXT( "Visualization thread dead" ) );
Console::Append( " " );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
VisModule::VisModule( char * szName, int iIndex, winampVisModule * mod, VisPlugin * plugin )
{
iArrayIndex = -1;
bActive = false;
bShouldQuit = false;
bAllowRender = false;
iNameLen = ( int )strlen( szName );
this->szName = new TCHAR[ iNameLen + 1 ];
ToTchar( this->szName, szName, iNameLen );
this->szName[ iNameLen ] = TEXT( '\0' );
this->iIndex = iIndex;
this->mod = mod;
this->plugin = plugin;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool VisModule::Start()
{
if( !mod ) return false;
if( bActive ) return false;
if( plugin->IsActive() ) return false;
////////////////////////////////////////////////////////////////////////////////
VisLock.Enter();
if( !active_vis_count )
{
active_vis_mods = new VisModule * [ 1 ];
active_vis_mods[ 0 ] = this;
}
else
{
VisModule ** new_active_vis_mods = new VisModule * [ active_vis_count + 1 ];
memcpy( new_active_vis_mods, active_vis_mods, active_vis_count * sizeof( VisModule * ) );
new_active_vis_mods[ active_vis_count ] = this;
delete [] active_vis_mods;
active_vis_mods = new_active_vis_mods;
}
VisLock.Leave();
////////////////////////////////////////////////////////////////////////////////
iArrayIndex = active_vis_count;
// Start
_beginthread( PlugThread, 1024 * 1024, ( PVOID )this );
bActive = true;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool VisModule::Stop()
{
if( !mod ) return false;
if( !bActive ) return false;
if( !plugin->IsActive() ) return false;
////////////////////////////////////////////////////////////////////////////////
VisLock.Enter();
bShouldQuit = true;
VisLock.Leave();
////////////////////////////////////////////////////////////////////////////////
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool VisModule::Config()
{
if( !mod ) return false;
if( !mod->Config ) return false;
mod->Config( mod );
return true;
}
+71
View File
@@ -0,0 +1,71 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_VIS_MODULE_H
#define PA_VIS_MODULE_H
#include "Global.h"
#include "VisPlugin.h"
#include <Process.h>
class VisModule;
class VisPlugin;
extern VisModule ** active_vis_mods;
extern int active_vis_count;
////////////////////////////////////////////////////////////////////////////////
/// Winamp visualization module wrapper
////////////////////////////////////////////////////////////////////////////////
class VisModule
{
public:
VisModule( char * szName, int iIndex, winampVisModule * mod, VisPlugin * plugin );
bool Start();
bool Config();
bool Stop();
inline bool IsActive() { return bActive; }
inline TCHAR * GetName() { return szName; }
inline int GetNameLen() { return iNameLen; }
private:
int iArrayIndex;
bool bActive;
bool bShouldQuit;
bool bAllowRender;
TCHAR * szName;
int iNameLen;
int iIndex;
winampVisModule * mod;
VisPlugin * plugin;
friend void PlugThread( PVOID pvoid );
friend void VSAAdd( void * data, int timestamp );
friend void VSAAddPCMData( void * PCMData, int nch, int bps, int timestamp );
friend int VSAGetMode( int * specNch, int * waveNch );
};
#endif // PA_VIS_MODULE_H
+189
View File
@@ -0,0 +1,189 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "VisPlugin.h"
#include "Unicode.h"
#include "Console.h"
#include "Main.h"
vector <VisPlugin *> vis_plugins; // extern
Lock VisLock = Lock( TEXT( "PLAINAMP_VIS_LOCK" ) ); // extern
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
VisPlugin::VisPlugin( TCHAR * szDllpath, bool bKeepLoaded ) : Plugin( szDllpath )
{
header = NULL;
if( !Load() )
{
return;
}
if( !bKeepLoaded )
{
Unload();
}
vis_plugins.push_back( this );
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool VisPlugin::Load()
{
// (1) Load DLL
hDLL = LoadLibrary( GetFullpath() );
if( !hDLL ) return false;
// (2) Find export
WINAMP_VIS_GETTER winampGetVisHeader =
( WINAMP_VIS_GETTER )GetProcAddress( hDLL, "winampVisGetHeader" );
if( winampGetVisHeader == NULL )
{
FreeLibrary( hDLL );
hDLL = NULL;
return false;
}
// (3) Get header
header = winampGetVisHeader();
if( header == NULL )
{
FreeLibrary( hDLL );
hDLL = NULL;
return false;
}
////////////////////////////////////////////////////////////////////////////////
// Forget old modules or we get them twice
if( !modules.empty() )
{
modules.clear();
}
////////////////////////////////////////////////////////////////////////////////
if( !szName )
{
// Note: The prefix is not removed to hide their
// origin at Nullsoft! It just reads easier.
if( !strnicmp( header->description, "nullsoft ", 9 ) )
{
header->description += 9;
}
iNameLen = ( int )strlen( header->description );
szName = new TCHAR[ iNameLen + 1 ];
ToTchar( szName, header->description, iNameLen );
szName[ iNameLen ] = TEXT( '\0' );
}
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Loading <%s>, %s" ), GetFilename(), szName );
Console::Append( szBuffer );
// (4) Get modules
winampVisModule * mod;
int iFound = 0;
while( true )
{
mod = header->getModule( iFound );
if( !mod ) break;
// (4a) Modify module
mod->hDllInstance = hDLL;
mod->hwndParent = WindowMain;
mod->sRate = 44100; // TODO
mod->nCh = 2; // TODO
// (4b) Add module to list
VisModule * vismod = new VisModule(
mod->description, // char * szName
iFound, // UINT uIndex
mod, // winampVisModule * mod
this // VisPlugin * plugin
);
modules.push_back( vismod );
iFound++;
_stprintf( szBuffer, TEXT( " %s" ), vismod->GetName() );
Console::Append( szBuffer );
}
Console::Append( TEXT( " " ) );
if( !iFound ) return false;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool VisPlugin::Unload()
{
if( !IsLoaded() ) return true;
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Unloading <%s>" ), GetFilename() );
Console::Append( szBuffer );
Console::Append( TEXT( " " ) );
printf( ">>>Unloading <%s>\n" , GetFilename() );
header = NULL;
/*
TODO
VisModule * walk;
vector <VisModule *>::iterator iter = modules.begin();
while( iter != modules.end() )
{
walk = *iter;
delete [] walk->szName;
delete walk;
iter++;
}
*/
FreeLibrary( hDLL );
hDLL = NULL;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool VisPlugin::IsActive()
{
vector <VisModule *>::iterator iter = modules.begin();
while( iter != modules.end() )
{
if( ( *iter )->IsActive() ) return true;
iter++;
}
return false;
}
+68
View File
@@ -0,0 +1,68 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_VIS_PLUGIN_H
#define PA_VIS_PLUGIN_H
#include "Global.h"
#include "Plugin.h"
#include "Winamp/Vis.h"
#include "VisModule.h"
#include "Lock.h"
#include <vector>
using namespace std;
typedef winampVisHeader * ( * WINAMP_VIS_GETTER )( void );
class VisModule;
class VisPlugin;
extern vector <VisPlugin *> vis_plugins;
extern Lock VisLock;
////////////////////////////////////////////////////////////////////////////////
/// Winamp visualization plugin wrapper
////////////////////////////////////////////////////////////////////////////////
class VisPlugin : public Plugin
{
public:
VisPlugin( TCHAR * szDllpath, bool bKeepLoaded );
bool Load();
bool Unload();
TCHAR * GetTypeString() { return TEXT( "Visual" ); }
int GetTypeStringLen() { return 6; }
PluginType GetType() { return PLUGIN_TYPE_VIS; }
bool IsActive();
private:
winampVisHeader * header;
vector<VisModule *> modules;
friend void ContextMenuVis( VisPlugin * vis, POINT * p );
};
#endif // PA_VIS_PLUGIN_H
+996
View File
@@ -0,0 +1,996 @@
// =======================================================================================
// WndprocWinamp is called repeatedly when the cursor is moved over the main window
// =======================================================================================
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Winamp.h"
#include "Playback.h"
#include "Playlist.h"
#include "Console.h"
#include "Main.h"
#include "Winamp/wa_ipc.h"
#include "Winamp/wa_msgids.h"
#include "AddDirectory.h"
#include "AddFiles.h"
#include "Prefs.h"
#include "PluginManager.h"
#include "Embed.h"
#include "Unicode.h"
#include "zlib/zlib.h"
#include "Rebar.h"
int IPC_GENHOTKEYS_ADD = 0;
int ID_DYNAMICLIBRARY = 0;
int IPC_GETPLAINBARTARGET = 0;
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndprocWinamp( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
//Console::Append( TEXT( "Winamp.cc:WndprocWinamp was called" ) );
switch( message )
{
case WM_COMMAND:
/*
{
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "WM_COMMAND <%i> <%i>" ), wp, lp );
Console::Append( szBuffer );
}
*/
switch( LOWORD( wp ) )
{
case WINAMP_FILE_QUIT:
PostMessage( WindowMain, WM_SYSCOMMAND, SC_CLOSE, 0 );
break;
case WINAMP_OPTIONS_PREFS:
Prefs::Show();
break;
/*
case WINAMP_OPTIONS_AOT: break;
case WINAMP_FILE_REPEAT: break;
case WINAMP_FILE_SHUFFLE: break;
case WINAMP_HIGH_PRIORITY: break;
*/
case WINAMP_FILE_PLAY:
AddFiles();
break;
/*
case WINAMP_OPTIONS_EQ: break;
case WINAMP_OPTIONS_ELAPSED: break;
case WINAMP_OPTIONS_REMAINING: break;
case WINAMP_OPTIONS_PLEDIT: break;
*/
case WINAMP_HELP_ABOUT:
About( hwnd );
break;
case WINAMP_MAINMENU:
{
POINT p;
GetCursorPos( &p );
CheckMenuItem(
main_context_menu,
PLAINAMP_TOGGLE_CONSOLE,
IsWindowVisible( WindowConsole ) ? MF_CHECKED : MF_UNCHECKED
);
CheckMenuItem(
main_context_menu,
PLAINAMP_TOGGLE_MANAGER,
IsWindowVisible( WindowManager ) ? MF_CHECKED : MF_UNCHECKED
);
TrackPopupMenu(
main_context_menu,
TPM_LEFTALIGN |
TPM_TOPALIGN |
TPM_RIGHTBUTTON,
p.x,
p.y,
0,
hwnd,
NULL
);
break;
}
case WINAMP_BUTTON1:
Playback::Prev();
Playback::UpdateSeek();
break;
case WINAMP_BUTTON2:
Playback::Play();
Playback::UpdateSeek();
break;
case WINAMP_BUTTON3:
Playback::Pause();
Playback::UpdateSeek();
break;
case WINAMP_BUTTON4:
Playback::Stop();
Playback::UpdateSeek();
break;
case WINAMP_BUTTON5:
Playback::Next();
Playback::UpdateSeek();
break;
/*
case WINAMP_BUTTON1_SHIFT: break;
case WINAMP_BUTTON2_SHIFT: break;
case WINAMP_BUTTON3_SHIFT: break;
case WINAMP_BUTTON4_SHIFT: break;
case WINAMP_BUTTON5_SHIFT: break;
case WINAMP_BUTTON1_CTRL: break;
case WINAMP_BUTTON2_CTRL: break;
case WINAMP_BUTTON3_CTRL: break;
case WINAMP_BUTTON4_CTRL: break;
case WINAMP_BUTTON5_CTRL: break;
*/
case WINAMP_VOLUMEUP:
Playback::Volume::Up();
// TODO Update slider
break;
case WINAMP_VOLUMEDOWN:
Playback::Volume::Down();
// TODO Update slider
break;
case WINAMP_FFWD5S:
Playback::Forward();
Playback::UpdateSeek();
break;
case WINAMP_REW5S:
Playback::Rewind();
Playback::UpdateSeek();
break;
/*
case WINAMP_NEXT_WINDOW: break;
case WINAMP_OPTIONS_WINDOWSHADE: break;
case WINAMP_OPTIONS_DSIZE: break;
case IDC_SORT_FILENAME: break;
case IDC_SORT_FILETITLE: break;
case IDC_SORT_ENTIREFILENAME: break;
case IDC_SELECTALL: break;
case IDC_SELECTNONE: break;
case IDC_SELECTINV: break;
case IDM_EQ_LOADPRE: break;
case IDM_EQ_LOADMP3: break;
case IDM_EQ_LOADDEFAULT: break;
case IDM_EQ_SAVEPRE: break;
case IDM_EQ_SAVEMP3: break;
case IDM_EQ_SAVEDEFAULT: break;
case IDM_EQ_DELPRE: break;
case IDM_EQ_DELMP3: break;
case IDC_PLAYLIST_PLAY: break;
case WINAMP_FILE_LOC: break;
case WINAMP_OPTIONS_EASYMOVE: break;
*/
case WINAMP_FILE_DIR:
AddDirectory();
break;
/*
case WINAMP_EDIT_ID3: break;
case WINAMP_TOGGLE_AUTOSCROLL: break;
case WINAMP_VISSETUP: break;
case WINAMP_PLGSETUP: break;
case WINAMP_VISPLUGIN: break;
case WINAMP_JUMP: break;
case WINAMP_JUMPFILE: break;
case WINAMP_JUMP10FWD: break;
case WINAMP_JUMP10BACK: break;
case WINAMP_PREVSONG: break;
case WINAMP_OPTIONS_EXTRAHQ: break;
*/
case ID_PE_NEW:
playlist->RemoveAll();
break;
case ID_PE_OPEN:
Playlist::DialogOpen();
break;
/*
case ID_PE_SAVE: break;
*/
case ID_PE_SAVEAS:
Playlist::DialogSaveAs();
break;
case ID_PE_SELECTALL:
playlist->SelectAll( true );
break;
case ID_PE_INVERT:
playlist->SelectInvert();
break;
case ID_PE_NONE:
playlist->SelectAll( false );
break;
/*
case ID_PE_ID3: break;
case ID_PE_S_TITLE: break;
case ID_PE_S_FILENAME: break;
case ID_PE_S_PATH: break;
case ID_PE_S_RANDOM: break;
case ID_PE_S_REV: break;
*/
case ID_PE_CLEAR:
playlist->RemoveAll();
break;
/*
case ID_PE_MOVEUP: break;
case ID_PE_MOVEDOWN: break;
case WINAMP_SELSKIN: break;
case WINAMP_VISCONF: break;
case ID_PE_NONEXIST: break;
case ID_PE_DELETEFROMDISK: break;
case ID_PE_CLOSE: break;
case WINAMP_VIS_SETOSC: break;
case WINAMP_VIS_SETANA: break;
case WINAMP_VIS_SETOFF: break;
case WINAMP_VIS_DOTSCOPE: break;
case WINAMP_VIS_LINESCOPE: break;
case WINAMP_VIS_SOLIDSCOPE: break;
case WINAMP_VIS_NORMANA: break;
case WINAMP_VIS_FIREANA: break;
case WINAMP_VIS_LINEANA: break;
case WINAMP_VIS_NORMVU: break;
case WINAMP_VIS_SMOOTHVU: break;
case WINAMP_VIS_FULLREF: break;
case WINAMP_VIS_FULLREF2: break;
case WINAMP_VIS_FULLREF3: break;
case WINAMP_VIS_FULLREF4: break;
case WINAMP_OPTIONS_TOGTIME: break;
case EQ_ENABLE: break;
case EQ_AUTO: break;
case EQ_PRESETS: break;
case WINAMP_VIS_FALLOFF0: break;
case WINAMP_VIS_FALLOFF1: break;
case WINAMP_VIS_FALLOFF2: break;
case WINAMP_VIS_FALLOFF3: break;
case WINAMP_VIS_FALLOFF4: break;
case WINAMP_VIS_PEAKS: break;
case ID_LOAD_EQF: break;
case ID_SAVE_EQF: break;
case ID_PE_ENTRY: break;
case ID_PE_SCROLLUP: break;
case ID_PE_SCROLLDOWN: break;
case WINAMP_MAIN_WINDOW: break;
case WINAMP_VIS_PFALLOFF0: break;
case WINAMP_VIS_PFALLOFF1: break;
case WINAMP_VIS_PFALLOFF2: break;
case WINAMP_VIS_PFALLOFF3: break;
case WINAMP_VIS_PFALLOFF4: break;
case ID_PE_TOP: break;
case ID_PE_BOTTOM: break;
case WINAMP_OPTIONS_WINDOWSHADE_PL: break;
case EQ_INC1: break;
case EQ_INC2: break;
case EQ_INC3: break;
case EQ_INC4: break;
case EQ_INC5: break;
case EQ_INC6: break;
case EQ_INC7: break;
case EQ_INC8: break;
case EQ_INC9: break;
case EQ_INC10: break;
case EQ_INCPRE: break;
case EQ_DECPRE: break;
case EQ_DEC1: break;
case EQ_DEC2: break;
case EQ_DEC3: break;
case EQ_DEC4: break;
case EQ_DEC5: break;
case EQ_DEC6: break;
case EQ_DEC7: break;
case EQ_DEC8: break;
case EQ_DEC9: break;
case EQ_DEC10: break;
case ID_PE_SCUP: break;
case ID_PE_SCDOWN: break;
case WINAMP_REFRESHSKIN: break;
case ID_PE_PRINT: break;
case ID_PE_EXTINFO: break;
case WINAMP_PLAYLIST_ADVANCE: break;
case WINAMP_VIS_LIN: break;
case WINAMP_VIS_BAR: break;
case WINAMP_OPTIONS_MINIBROWSER: break;
case MB_FWD: break;
case MB_BACK: break;
case MB_RELOAD: break;
case MB_OPENMENU: break;
case MB_OPENLOC: break;
case WINAMP_NEW_INSTANCE: break;
case MB_UPDATE: break;
case WINAMP_OPTIONS_WINDOWSHADE_EQ: break;
case EQ_PANLEFT: break;
case EQ_PANRIGHT: break;
case WINAMP_GETMORESKINS: break;
case WINAMP_VIS_OPTIONS: break;
case WINAMP_PE_SEARCH: break;
case ID_PE_BOOKMARK: break;
case WINAMP_EDIT_BOOKMARKS: break;
case WINAMP_MAKECURBOOKMARK: break;
case ID_MAIN_PLAY_BOOKMARK_NONE: break;
case ID_MAIN_PLAY_AUDIOCD: break;
case ID_MAIN_PLAY_AUDIOCD2: break;
case ID_MAIN_PLAY_AUDIOCD3: break;
case ID_MAIN_PLAY_AUDIOCD4: break;
case WINAMP_OPTIONS_VIDEO: break;
case ID_VIDEOWND_ZOOMFULLSCREEN: break;
case ID_VIDEOWND_ZOOM100: break;
case ID_VIDEOWND_ZOOM200: break;
case ID_VIDEOWND_ZOOM50: break;
case ID_VIDEOWND_VIDEOOPTIONS: break;
case WINAMP_MINIMIZE: break;
case ID_PE_FONTBIGGER: break;
case ID_PE_FONTSMALLER: break;
case WINAMP_VIDEO_TOGGLE_FS: break;
case WINAMP_VIDEO_TVBUTTON: break;
case WINAMP_LIGHTNING_CLICK: break;
case ID_FILE_ADDTOLIBRARY: break;
case ID_HELP_HELPTOPICS: break;
case ID_HELP_GETTINGSTARTED: break;
case ID_HELP_WINAMPFORUMS: break;
*/
case ID_PLAY_VOLUMEUP:
Playback::Volume::Up();
// TODO Update slider
break;
case ID_PLAY_VOLUMEDOWN:
Playback::Volume::Down();
// TODO Update slider
break;
/*
case ID_PEFILE_OPENPLAYLISTFROMLIBRARY_NOPLAYLISTSINLIBRARY: break;
case ID_PEFILE_ADDFROMLIBRARY: break;
case ID_PEFILE_CLOSEPLAYLISTEDITOR: break;
case ID_PEPLAYLIST_PLAYLISTPREFERENCES: break;
case ID_MLFILE_NEWPLAYLIST: break;
case ID_MLFILE_LOADPLAYLIST: break;
case ID_MLFILE_SAVEPLAYLIST: break;
case ID_MLFILE_ADDMEDIATOLIBRARY: break;
case ID_MLFILE_CLOSEMEDIALIBRARY: break;
case ID_MLVIEW_NOWPLAYING: break;
case ID_MLVIEW_LOCALMEDIA_ALLMEDIA: break;
case ID_MLVIEW_LOCALMEDIA_AUDIO: break;
case ID_MLVIEW_LOCALMEDIA_VIDEO: break;
case ID_MLVIEW_PLAYLISTS_NOPLAYLISTINLIBRARY: break;
case ID_MLVIEW_INTERNETRADIO: break;
case ID_MLVIEW_INTERNETTV: break;
case ID_MLVIEW_LIBRARYPREFERENCES: break;
case ID_MLVIEW_DEVICES_NOAVAILABLEDEVICE: break;
case ID_MLFILE_IMPORTCURRENTPLAYLIST: break;
case ID_MLVIEW_MEDIA: break;
case ID_MLVIEW_PLAYLISTS: break;
case ID_MLVIEW_MEDIA_ALLMEDIA: break;
case ID_MLVIEW_DEVICES: break;
case ID_FILE_SHOWLIBRARY: break;
case ID_FILE_CLOSELIBRARY: break;
case ID_POST_PLAY_PLAYLIST: break;
case ID_VIS_NEXT: break;
case ID_VIS_PREV: break;
case ID_VIS_RANDOM: break;
case ID_MANAGEPLAYLISTS: break;
case ID_PREFS_SKIN_SWITCHTOSKIN: break;
case ID_PREFS_SKIN_DELETESKIN: break;
case ID_PREFS_SKIN_RENAMESKIN: break;
case ID_VIS_FS: break;
case ID_VIS_CFG: break;
case ID_VIS_MENU: break;
case ID_VIS_SET_FS_FLAG: break;
case ID_PE_SHOWPLAYING: break;
case ID_HELP_REGISTERWINAMPPRO: break;
case ID_PE_MANUAL_ADVANCE: break;
case WA_SONG_5_STAR_RATING: break;
case WA_SONG_4_STAR_RATING: break;
case WA_SONG_3_STAR_RATING: break;
case WA_SONG_2_STAR_RATING: break;
case WA_SONG_1_STAR_RATING: break;
case WA_SONG_NO_RATING: break;
case PL_SONG_5_STAR_RATING: break;
case PL_SONG_4_STAR_RATING: break;
case PL_SONG_3_STAR_RATING: break;
case PL_SONG_2_STAR_RATING: break;
case PL_SONG_1_STAR_RATING: break;
case PL_SONG_NO_RATING: break;
case AUDIO_TRACK_ONE: break;
case VIDEO_TRACK_ONE: break;
case ID_SWITCH_COLOURTHEME: break;
case ID_GENFF_LIMIT: break;
*/
case PLAINAMP_TOGGLE_CONSOLE:
ShowWindow( WindowConsole, IsWindowVisible( WindowConsole ) ? SW_HIDE : SW_SHOW );
break;
case PLAINAMP_TOGGLE_MANAGER:
ShowWindow( WindowManager, IsWindowVisible( WindowManager ) ? SW_HIDE : SW_SHOW );
break;
case PLAINAMP_PL_REM_SEL:
playlist->RemoveSelected( true );
break;
case PLAINAMP_PL_REM_CROP:
playlist->RemoveSelected( false );
break;
default:
{
/*
if( wp == ID_DYNAMICLIBRARY )
{
// Stupid dnylib workaround
PostMessage( hwnd, WM_COMMAND, ID_DYNAMICLIBRARY | ( 1 << 16 ), 0 );
}
*/
if( LOWORD( wp ) < 40001 ) break;
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "WM_COMMAND <%i> <%i>" ), wp, lp );
Console::Append( szBuffer );
Console::Append( TEXT( "NOT handled" ) );
Console::Append( " " );
}
}
break;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
case WM_WA_IPC:
/*
{
TCHAR szBuffer[ 5000 ];
if( lp != 2006 )
{
_stprintf( szBuffer, TEXT( "WM_WA_IPC <%i> <%i>" ), wp, lp );
}
else
{
// Hotkey sent as strings!
// Idea: make stl map
_stprintf( szBuffer, TEXT( "WM_WA_IPC <%s> <%i>" ), ( char * )wp, lp );
}
Console::Append( szBuffer );
}
*/
switch( lp )
{
case IPC_GETVERSION:
return 0x5010; // 5.10
/*
case IPC_GETREGISTEREDVERSION: break;
case IPC_PLAYFILE: break;
case IPC_ENQUEUEFILE: break;
*/
case IPC_DELETE:
playlist->RemoveAll();
break;
/*
case IPC_DELETE_INT: break;
*/
case IPC_STARTPLAY:
Playback::Play();
Playback::UpdateSeek();
break;
/*
case IPC_STARTPLAY_INT: break;
case IPC_CHDIR: break;
*/
case IPC_ISPLAYING: // untested
return ( Playback::IsPlaying() ? ( Playback::IsPaused() ? 3 : 1 ) : 0 );
/*
case IPC_GETOUTPUTTIME: break;
case IPC_JUMPTOTIME: break;
case IPC_GETMODULENAME: break;
case IPC_EX_ISRIGHTEXE: break;
case IPC_WRITEPLAYLIST: break;
*/
case IPC_SETPLAYLISTPOS:
playlist->SetCurIndex( ( int )wp );
break;
case IPC_SETVOLUME: break;
Playback::Volume::Set( ( int )wp );
// TODO Update slider
break;
case IPC_SETPANNING: break;
Playback::Pan::Set( ( int )wp );
// TODO Update slider
break;
case IPC_GETLISTLENGTH:
return playlist->GetSize();
case IPC_GETLISTPOS:
return playlist->GetCurIndex();
/*
case IPC_GETINFO: break;
case IPC_GETEQDATA: break;
// TODO
case IPC_SETEQDATA: break;
// TODO
case IPC_ADDBOOKMARK: break;
case IPC_INSTALLPLUGIN: break;
case IPC_RESTARTWINAMP: break;
case IPC_ISFULLSTOP: break;
case IPC_INETAVAILABLE: break;
case IPC_UPDTITLE: break;
case IPC_REFRESHPLCACHE: break;
case IPC_GET_SHUFFLE: break;
case IPC_GET_REPEAT: break;
case IPC_SET_SHUFFLE: break;
case IPC_SET_REPEAT: break;
case IPC_ENABLEDISABLE_ALL_WINDOWS: break;
*/
case IPC_GETWND:
{
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "IPC_GETWND <%i>" ), wp );
Console::Append( szBuffer );
Console::Append( " " );
}
switch( wp )
{
case IPC_GETWND_EQ: break;
case IPC_GETWND_PE: return ( LRESULT )WindowMain;
case IPC_GETWND_MB: break;
case IPC_GETWND_VIDEO: break;
}
return ( LRESULT )NULL;
case IPC_ISWNDVISIBLE:
{
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "IPC_ISWNDVISIBLE <%i>" ), wp );
Console::Append( szBuffer );
Console::Append( " " );
}
switch( wp )
{
case IPC_GETWND_EQ: break;
case IPC_GETWND_PE: return 1;
case IPC_GETWND_MB: break;
case IPC_GETWND_VIDEO: break;
}
return 0;
/*
case IPC_SETSKIN: break;
case IPC_GETSKIN: break;
case IPC_EXECPLUG: break;
*/
case IPC_GETPLAYLISTFILE:
{
static char szAnsiFilename[ 2000 ] = "\0";
Playlist::GetFilename( ( int )wp, szAnsiFilename, 1999 );
return ( LRESULT )szAnsiFilename;
}
case IPC_GETPLAYLISTTITLE:
{
static char szAnsiTitle[ 2000 ] = "\0";
Playlist::GetTitle( ( int )wp, szAnsiTitle, 1999 );
return ( LRESULT )szAnsiTitle;
}
/*
case IPC_GETHTTPGETTER: break;
case IPC_MBOPEN: break;
case IPC_CHANGECURRENTFILE: break;
case IPC_GETMBURL: break;
case IPC_MBBLOCK: break;
case IPC_MBOPENREAL: break;
case IPC_ADJUST_OPTIONSMENUPOS: break;
*/
case IPC_GET_HMENU:
{
switch( wp )
{
case 0:
return ( LRESULT )main_context_menu;
/*
case 1: break;
case 2: break;
case 3: break;
case 4: break;
*/
}
return ( LRESULT )NULL;
}
case IPC_GET_EXTENDED_FILE_INFO:
Console::Append( "IPC_GET_EXTENDED_FILE_INFO" );
Console::Append( TEXT( "NOT handled" ) );
Console::Append( " " );
break;
/*
case IPC_GET_EXTENDED_FILE_INFO_HOOKABLE: break;
case IPC_GET_BASIC_FILE_INFO: break;
*/
case IPC_GET_EXTLIST:
// TODO
return ( LRESULT )GlobalAlloc( GMEM_ZEROINIT, 2 ); // "\0\0"
/*
case IPC_INFOBOX: break;
case IPC_SET_EXTENDED_FILE_INFO: break;
case IPC_WRITE_EXTENDED_FILE_INFO: break;
case IPC_FORMAT_TITLE: break;
*/
// =======================================================================================
// Let's remove this
/*
case IPC_GETUNCOMPRESSINTERFACE:
if( wp == 0x10100000 )
{
Console::Append( "IPC_GETUNCOMPRESSINTERFACE @ wa_inflate_struct" );
Console::Append( TEXT( "NOT handled" ) );
Console::Append( " " );
}
else
{
Console::Append( "IPC_GETUNCOMPRESSINTERFACE @ zlib" );
Console::Append( " " );
return ( LRESULT )uncompress;
}
break;
*/
// =======================================================================================
case IPC_ADD_PREFS_DLG:
Prefs::AddPage( ( prefsDlgRec * )wp );
break;
/*
case IPC_REMOVE_PREFS_DLG: break;
*/
case IPC_OPENPREFSTOPAGE:
Prefs::Show( ( prefsDlgRec * )wp );
break;
case IPC_GETINIFILE:
{
static char szWinampInipath[ MAX_PATH ] = "";
if( *szWinampInipath == '\0' )
{
GetModuleFileNameA( NULL, szWinampInipath, MAX_PATH - 1 );
char * szWalk = szWinampInipath + strlen( szWinampInipath ) - 1;
while( ( szWalk > szWinampInipath ) && ( *szWalk != '.' ) ) szWalk--;
szWalk++;
strcpy( szWalk, "ini" );
}
return ( LRESULT )szWinampInipath;
}
case IPC_GETINIDIRECTORY:
{
// TODO: trailing slash or not???
static char szPluginInipath[ MAX_PATH ] = "";
if( *szPluginInipath == '\0' )
{
GetModuleFileNameA( NULL, szPluginInipath, MAX_PATH - 1 );
char * szWalk = szPluginInipath + strlen( szPluginInipath ) - 1;
while( ( szWalk > szPluginInipath ) && ( *szWalk != '\\' ) ) szWalk--;
szWalk++;
strcpy( szWalk, TEXT( "Plugins" ) );
}
return ( LRESULT )szPluginInipath;
}
/*
case IPC_SPAWNBUTTONPOPUP: break;
case IPC_OPENURLBOX: break;
*/
case IPC_OPENFILEBOX:
AddFiles();
break;
case IPC_OPENDIRBOX:
AddDirectory();
break;
case IPC_GET_GENSKINBITMAP:
{
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "IPC_GET_GENSKINBITMAP <%i>" ), wp );
Console::Append( szBuffer );
switch( wp )
{
case 0:
{
// TODO: make it work
// Gen.bmp?
static HBITMAP hBitmap = NULL;
static BYTE * image = NULL;
if( !hBitmap )
{
const int iWidth = 200; // 194;
const int iHeight = 300; // 109;
const int bpp = 24;
int bytes_per_row = iWidth * ( bpp / 8 );
const int diff = bytes_per_row % 4;
if( diff ) bytes_per_row += ( 4 - diff );
const int size_in_bytes = bytes_per_row * iHeight;
image = new BYTE[ size_in_bytes ];
hBitmap = CreateBitmap(
iWidth, // int nWidth
iHeight, // int nHeight
1, // UINT cPlanes
bpp, // UINT cBitsPerPel
image // CONST VOID * lpvBits
);
memset( image, 255, size_in_bytes );
}
return ( LRESULT )hBitmap;
}
default:
{
Console::Append( TEXT( "NOT handled" ) );
}
}
Console::Append( TEXT( " " ) );
break;
}
case IPC_GET_EMBEDIF:
// TODO
if( !wp )
{
return ( LRESULT )Embed::Embed;
}
else
{
return ( LRESULT )Embed::Embed( ( embedWindowState * )wp );
}
break;
/*
case IPC_EMBED_ENUM: break;
case IPC_EMBED_ISVALID: break;
case IPC_CONVERTFILE: break;
case IPC_CONVERTFILE_END: break;
case IPC_CONVERT_CONFIG: break;
case IPC_CONVERT_CONFIG_END: break;
case IPC_GETSADATAFUNC: break;
case IPC_ISMAINWNDVISIBLE: break;
case IPC_SETPLEDITCOLORS: break;
case IPC_SPAWNEQPRESETMENU: break;
case IPC_SPAWNFILEMENU: break;
case IPC_SPAWNOPTIONSMENU: break;
case IPC_SPAWNWINDOWSMENU: break;
case IPC_SPAWNHELPMENU: break;
case IPC_SPAWNPLAYMENU: break;
case IPC_SPAWNPEFILEMENU: break;
case IPC_SPAWNPEPLAYLISTMENU: break;
case IPC_SPAWNPESORTMENU: break;
case IPC_SPAWNPEHELPMENU: break;
case IPC_SPAWNMLFILEMENU: break;
case IPC_SPAWNMLVIEWMENU: break;
case IPC_SPAWNMLHELPMENU: break;
case IPC_SPAWNPELISTOFPLAYLISTS: break;
case WM_WA_SYSTRAY: break;
case IPC_IS_PLAYING_VIDEO: break;
case IPC_GET_IVIDEOOUTPUT: break;
*/
case IPC_CB_ONSHOWWND:
case IPC_CB_ONHIDEWND:
case IPC_CB_GETTOOLTIP:
case IPC_CB_MISC:
case IPC_CB_CONVERT_STATUS:
case IPC_CB_CONVERT_DONE:
break;
/*
case IPC_ADJUST_FFWINDOWSMENUPOS: break;
case IPC_ISDOUBLESIZE: break;
case IPC_ADJUST_FFOPTIONSMENUPOS: break;
*/
case IPC_GETTIMEDISPLAYMODE:
return 0; // == elapsed time
/*
case IPC_SETVISWND: break;
case IPC_GETVISWND: break;
case IPC_ISVISRUNNING: break;
*/
case IPC_CB_VISRANDOM: break;
/*
case IPC_SETIDEALVIDEOSIZE: break;
case IPC_GETSTOPONVIDEOCLOSE: break;
case IPC_SETSTOPONVIDEOCLOSE: break;
*/
case IPC_TRANSLATEACCELERATOR:
Console::Append( TEXT( "IPC_TRANSLATEACCELERATOR" ) );
Console::Append( TEXT( "NOT handled" ) );
Console::Append( TEXT( " " ) );
break;
case IPC_CB_ONTOGGLEAOT: break;
/*
case IPC_GETPREFSWND: break;
case IPC_SET_PE_WIDTHHEIGHT: break;
case IPC_GETLANGUAGEPACKINSTANCE: break;
*/
case IPC_CB_PEINFOTEXT:
case IPC_CB_OUTPUTCHANGED:
break;
/*
case IPC_GETOUTPUTPLUGIN: break;
case IPC_SETDRAWBORDERS: break;
case IPC_DISABLESKINCURSORS: break;
*/
case IPC_CB_RESETFONT: break;
/*
case IPC_IS_FULLSCREEN: break;
case IPC_SET_VIS_FS_FLAG: break;
case IPC_SHOW_NOTIFICATION: break;
case IPC_GETSKININFO: break;
case IPC_GET_MANUALPLADVANCE: break;
case IPC_SET_MANUALPLADVANCE: break;
case IPC_GET_NEXT_PLITEM: break;
case IPC_GET_PREVIOUS_PLITEM: break;
case IPC_IS_WNDSHADE: break;
case IPC_SETRATING: break;
case IPC_GETRATING: break;
case IPC_GETNUMAUDIOTRACKS: break;
case IPC_GETNUMVIDEOTRACKS: break;
case IPC_GETAUDIOTRACK: break;
case IPC_GETVIDEOTRACK: break;
case IPC_SETAUDIOTRACK: break;
case IPC_SETVIDEOTRACK: break;
case IPC_PUSH_DISABLE_EXIT: break;
case IPC_POP_DISABLE_EXIT: break;
case IPC_IS_EXIT_ENABLED: break;
case IPC_IS_AOT: break;
case IPC_PLCMD: break;
case IPC_MBCMD: break;
case IPC_VIDCMD: break;
case IPC_MBURL: break;
case IPC_MBGETCURURL: break;
case IPC_MBGETDESC: break;
case IPC_MBCHECKLOCFILE: break;
case IPC_MBREFRESH: break;
case IPC_MBGETDEFURL: break;
case IPC_STATS_LIBRARY_ITEMCNT: break;
case IPC_FF_FIRST: break;
case IPC_FF_LAST: break;
case IPC_GETDROPTARGET: break;
case IPC_PLAYLIST_MODIFIED: break;
case IPC_PLAYING_FILE: break;
case IPC_FILE_TAG_MAY_HAVE_UPDATED: break;
case IPC_ALLOW_PLAYTRACKING: break;
*/
case IPC_HOOK_OKTOQUIT:
return 1; // Okay
/*
case IPC_WRITECONFIG: break;
*/
case IPC_REGISTER_WINAMP_IPCMESSAGE:
{
// TODO convert to TCHAR????
UINT res = RegisterWindowMessage( ( LPCTSTR )wp );
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Message \"%s\" registered as #%i" ), wp, res );
Console::Append( szBuffer );
Console::Append( " " );
if( !stricmp( ( char * )wp, "GenHotkeysAdd" ) )
{
IPC_GENHOTKEYS_ADD = res;
}
else if( !stricmp( ( char * )wp, "Dynamic Library" ) )
{
ID_DYNAMICLIBRARY = res;
}
else if( !stricmp( ( char * )wp, "IPC_GETPLAINBARTARGET" ) )
{
IPC_GETPLAINBARTARGET = res;
}
return res;
}
case 2006: // undocumented, name IPC_CB_HOTKEY or so later and ask to add this to sdk
{
// Hotkey sent as strings!
// Idea: make stl map
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "Hotkey \"%s\" detected" ), wp );
Console::Append( szBuffer );
Console::Append( " " );
return 1; // Accept???
}
default:
{
if( lp == IPC_GENHOTKEYS_ADD )
{
break;
}
else if( lp == IPC_GETPLAINBARTARGET )
{
return ( LRESULT )( IsWindowVisible( WindowVis ) ? WindowVis : NULL );
}
TCHAR szBuffer[ 5000 ];
_stprintf( szBuffer, TEXT( "WM_WA_IPC <%i> <%i>" ), wp, lp );
Console::Append( szBuffer );
Console::Append( TEXT( "NOT handled" ) );
Console::Append( " " );
}
}
break;
case WM_WA_MPEG_EOF:
Playback::NotifyTrackEnd();
Playback::Next();
break;
case WM_COPYDATA:
{
if( !lp ) return FALSE;
COPYDATASTRUCT * cds = ( COPYDATASTRUCT * )lp;
switch( cds->dwData )
{
case IPC_PLAYFILE:
{
const int iLen = cds->cbData;
if( !iLen ) return FALSE;
TCHAR * szKeep = new TCHAR[ iLen + 1 ];
ToTchar( szKeep, ( char * )cds->lpData, iLen );
szKeep[ iLen ] = TEXT( '\0' );
playlist->PushBack( szKeep );
return TRUE;
}
}
return FALSE;
}
}
return DefWindowProc( hwnd, message, wp, lp );
}
+26
View File
@@ -0,0 +1,26 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#ifndef PA_WINAMP_H
#define PA_WINAMP_H
#include "Global.h"
LRESULT CALLBACK WndprocWinamp( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
#endif // PA_WINAMP_H
+47
View File
@@ -0,0 +1,47 @@
#ifndef WINAMP_DSP_H
#define WINAMP_DSP_H
#include <windows.h>
// DSP plugin interface
// notes:
// any window that remains in foreground should optimally pass unused
// keystrokes to the parent (winamp's) window, so that the user
// can still control it. As for storing configuration,
// Configuration data should be stored in <dll directory>\plugin.ini
// (look at the vis plugin for configuration code)
typedef struct winampDSPModule {
char *description; // description
HWND hwndParent; // parent window (filled in by calling app)
HINSTANCE hDllInstance; // instance handle to this DLL (filled in by calling app)
void (*Config)(struct winampDSPModule *this_mod); // configuration dialog (if needed)
int (*Init)(struct winampDSPModule *this_mod); // 0 on success, creates window, etc (if needed)
// modify waveform samples: returns number of samples to actually write
// (typically numsamples, but no more than twice numsamples, and no less than half numsamples)
// numsamples should always be at least 128. should, but I'm not sure
int (*ModifySamples)(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate);
void (*Quit)(struct winampDSPModule *this_mod); // called when unloading
void *userData; // user data, optional
} winampDSPModule;
typedef struct {
int version; // DSP_HDRVER
char *description; // description of library
winampDSPModule* (*getModule)(int); // module retrieval function
} winampDSPHeader;
// exported symbols
typedef winampDSPHeader* (*winampDSPGetHeaderType)();
// header version: 0x20 == 0.20 == winamp 2.0
#define DSP_HDRVER 0x20
#endif // WINAMP_DSP_H
+28
View File
@@ -0,0 +1,28 @@
#ifndef WINAMP_GEN_H
#define WINAMP_GEN_H
#define GPPHDR_VER 0x10
typedef struct {
int version;
char *description;
int (*init)();
void (*config)();
void (*quit)();
HWND hwndParent;
HINSTANCE hDllInstance;
} winampGeneralPurposePlugin;
typedef winampGeneralPurposePlugin * ( * winampGeneralPurposePluginGetter )();
// extern winampGeneralPurposePlugin * gen_plugins[ 256 ];
#endif // WINAMP_GEN_H
+119
View File
@@ -0,0 +1,119 @@
#ifndef WINAMP_IN_H
#define WINAMP_IN_H
#include <windows.h>
#include "out.h"
// note: exported symbol is now winampGetInModule2.
#define IN_VER 0x100
// Changed
// void (*VSASetInfo)(int nch, int srate);
// to
// void (*VSASetInfo)(int srate, int nch);
// since the old one is wrong!
//
// Otherwise in_mp3 is the problem!?...
typedef struct
{
int version; // module type (IN_VER)
char *description; // description of module, with version string
HWND hMainWindow; // winamp's main window (filled in by winamp)
HINSTANCE hDllInstance; // DLL instance handle (Also filled in by winamp)
char *FileExtensions; // "mp3\0Layer 3 MPEG\0mp2\0Layer 2 MPEG\0mpg\0Layer 1 MPEG\0"
// May be altered from Config, so the user can select what they want
int is_seekable; // is this stream seekable?
int UsesOutputPlug; // does this plug-in use the output plug-ins? (musn't ever change, ever :)
void (*Config)(HWND hwndParent); // configuration dialog
void (*About)(HWND hwndParent); // about dialog
void (*Init)(); // called at program init
void (*Quit)(); // called at program quit
void (*GetFileInfo)(char *file, char *title, int *length_in_ms); // if file == NULL, current playing is used
int (*InfoBox)(char *file, HWND hwndParent);
int (*IsOurFile)(char *fn); // called before extension checks, to allow detection of mms://, etc
// playback stuff
int (*Play)(char *fn); // return zero on success, -1 on file-not-found, some other value on other (stopping winamp) error
void (*Pause)(); // pause stream
void (*UnPause)(); // unpause stream
int (*IsPaused)(); // ispaused? return 1 if paused, 0 if not
void (*Stop)(); // stop (unload) stream
// time stuff
int (*GetLength)(); // get length in ms
int (*GetOutputTime)(); // returns current output time in ms. (usually returns outMod->GetOutputTime()
void (*SetOutputTime)(int time_in_ms); // seeks to point in stream (in ms). Usually you signal yoru thread to seek, which seeks and calls outMod->Flush()..
// volume stuff
void (*SetVolume)(int volume); // from 0 to 255.. usually just call outMod->SetVolume
void (*SetPan)(int pan); // from -127 to 127.. usually just call outMod->SetPan
// in-window builtin vis stuff
void (*SAVSAInit)(int maxlatency_in_ms, int srate); // call once in Play(). maxlatency_in_ms should be the value returned from outMod->Open()
// call after opening audio device with max latency in ms and samplerate
void (*SAVSADeInit)(); // call in Stop()
// simple vis supplying mode
void (*SAAddPCMData)(void *PCMData, int nch, int bps, int timestamp);
// sets the spec data directly from PCM data
// quick and easy way to get vis working :)
// needs at least 576 samples :)
// advanced vis supplying mode, only use if you're cool. Use SAAddPCMData for most stuff.
int (*SAGetMode)(); // gets csa (the current type (4=ws,2=osc,1=spec))
// use when calling SAAdd()
void (*SAAdd)(void *data, int timestamp, int csa); // sets the spec data, filled in by winamp
// vis stuff (plug-in)
// simple vis supplying mode
void (*VSAAddPCMData)(void *PCMData, int nch, int bps, int timestamp); // sets the vis data directly from PCM data
// quick and easy way to get vis working :)
// needs at least 576 samples :)
// advanced vis supplying mode, only use if you're cool. Use VSAAddPCMData for most stuff.
int (*VSAGetMode)(int *specNch, int *waveNch); // use to figure out what to give to VSAAdd
void (*VSAAdd)(void *data, int timestamp); // filled in by winamp, called by plug-in
// call this in Play() to tell the vis plug-ins the current output params.
void (*VSASetInfo)(int srate, int nch);
// dsp plug-in processing:
// (filled in by winamp, called by input plug)
// returns 1 if active (which means that the number of samples returned by dsp_dosamples
// could be greater than went in.. Use it to estimate if you'll have enough room in the
// output buffer
int (*dsp_isactive)();
// returns number of samples to output. This can be as much as twice numsamples.
// be sure to allocate enough buffer for samples, then.
int (*dsp_dosamples)(short int *samples, int numsamples, int bps, int nch, int srate);
// eq stuff
void (*EQSet)(int on, char data[10], int preamp); // 0-64 each, 31 is +0, 0 is +12, 63 is -12. Do nothing to ignore.
// info setting (filled in by winamp)
void (*SetInfo)(int bitrate, int srate, int stereo, int synched); // if -1, changes ignored? :)
Out_Module *outMod; // filled in by winamp, optionally used :)
} In_Module;
#endif // WINAMP_IN_H
+69
View File
@@ -0,0 +1,69 @@
#ifndef WINAMP_OUT_H
#define WINAMP_OUT_H
#include <windows.h>
// [ids]
// waveout 32
// disk 33
// dsound 38
// xfade 63
// gapless 64
// null 65
// mm2 69
#define OUT_VER 0x10
typedef struct
{
int version; // module version (OUT_VER)
char *description; // description of module, with version string
int id; // module id. each input module gets its own. non-nullsoft modules should
// be >= 65536.
HWND hMainWindow; // winamp's main window (filled in by winamp)
HINSTANCE hDllInstance; // DLL instance handle (filled in by winamp)
void (*Config)(HWND hwndParent); // configuration dialog
void (*About)(HWND hwndParent); // about dialog
void (*Init)(); // called when loaded
void (*Quit)(); // called when unloaded
int (*Open)(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms);
// returns >=0 on success, <0 on failure
// NOTENOTENOTE: bufferlenms and prebufferms are ignored in most if not all output plug-ins.
// ... so don't expect the max latency returned to be what you asked for.
// returns max latency in ms (0 for diskwriters, etc)
// bufferlenms and prebufferms must be in ms. 0 to use defaults.
// prebufferms must be <= bufferlenms
void (*Close)(); // close the ol' output device.
int (*Write)(char *buf, int len);
// 0 on success. Len == bytes to write (<= 8192 always). buf is straight audio data.
// 1 returns not able to write (yet). Non-blocking, always.
int (*CanWrite)(); // returns number of bytes possible to write at a given time.
// Never will decrease unless you call Write (or Close, heh)
int (*IsPlaying)(); // non0 if output is still going or if data in buffers waiting to be
// written (i.e. closing while IsPlaying() returns 1 would truncate the song
int (*Pause)(int pause); // returns previous pause state
void (*SetVolume)(int volume); // volume is 0-255
void (*SetPan)(int pan); // pan is -128 to 128
void (*Flush)(int t); // flushes buffers and restarts output at time t (in ms)
// (used for seeking)
int (*GetOutputTime)(); // returns played time in MS
int (*GetWrittenTime)(); // returns time written in MS (used for synching up vis stuff)
} Out_Module;
#endif // WINAMP_OUT_H
+57
View File
@@ -0,0 +1,57 @@
#ifndef WINAMP_VIS_H
#define WINAMP_VIS_H
// notes:
// any window that remains in foreground should optimally pass
// keystrokes to the parent (winamp's) window, so that the user
// can still control it. unless escape is hit, or some option
// key specific to the vis is hit. As for storing configuration,
// Configuration data should be stored in <dll directory>\plugin.ini
// Look at the example plugin for a framework.
// ints are 32 bits, and structure members are aligned on the default 8 byte boundaries
// tested with VC++ 4.2 and 5.0
#include <windows.h>
typedef struct winampVisModule {
char *description; // description of module
HWND hwndParent; // parent window (filled in by calling app)
HINSTANCE hDllInstance; // instance handle to this DLL (filled in by calling app)
int sRate; // sample rate (filled in by calling app)
int nCh; // number of channels (filled in...)
int latencyMs; // latency from call of RenderFrame to actual drawing
// (calling app looks at this value when getting data)
int delayMs; // delay between calls in ms
// the data is filled in according to the respective Nch entry
int spectrumNch;
int waveformNch;
unsigned char spectrumData[2][576];
unsigned char waveformData[2][576];
void (*Config)(struct winampVisModule *this_mod); // configuration dialog
int (*Init)(struct winampVisModule *this_mod); // 0 on success, creates window, etc
int (*Render)(struct winampVisModule *this_mod); // returns 0 if successful, 1 if vis should end
void (*Quit)(struct winampVisModule *this_mod); // call when done
void *userData; // user data, optional
} winampVisModule;
typedef struct {
int version; // VID_HDRVER
char *description; // description of library
winampVisModule* (*getModule)(int);
} winampVisHeader;
// exported symbols
typedef winampVisHeader* (*winampVisGetHeaderType)();
// version of current module (0x101 == 1.01)
#define VIS_HDRVER 0x101
#endif // WINAMP_VIS_H
File diff suppressed because it is too large. Load diff
+297
View File
@@ -0,0 +1,297 @@
/*
** wa_msgids.h (created 14/04/2004 12:23:19 PM)
** Created from wa_ipc.h and resource.h from the language sdk
** by Darren Owen aka DrO
**
** This a simple header file which defines the message ids to allow you to control
** Winamp in keeping with the old frontend.h (R.I.P.)
**
**
** Version History:
**
** v1.0 :: intial version with ids for Winamp 5.02+
** v1.0a :: fixed the file to work on compile
** v1.1 :: added the msg id for 'Manual Playlist Advance'
** v1.2 :: added in song rating menu items
**
**
** How to use:
**
** To send these, use the format:
**
** SendMessage(hwnd_winamp, WM_COMMAND,command_name,0);
**
** For other languages such as Visual Basic, Pascal, etc you will need to use
** the equivalent calling SendMessage(..) calling convention
**
**
** Notes:
**
** IDs 42000 to 45000 are reserved for gen_ff
** IDs from 45000 to 57000 are reserved for library
**
*/
#ifndef _WA_MSGIDS_H_
#define _WA_MSGIDS_H_
#define WINAMP_FILE_QUIT 40001
#define WINAMP_OPTIONS_PREFS 40012 // pops up the preferences
#define WINAMP_OPTIONS_AOT 40019 // toggles always on top
#define WINAMP_FILE_REPEAT 40022
#define WINAMP_FILE_SHUFFLE 40023
#define WINAMP_HIGH_PRIORITY 40025
#define WINAMP_FILE_PLAY 40029 // pops up the load file(s) box
#define WINAMP_OPTIONS_EQ 40036 // toggles the EQ window
#define WINAMP_OPTIONS_ELAPSED 40037
#define WINAMP_OPTIONS_REMAINING 40038
#define WINAMP_OPTIONS_PLEDIT 40040 // toggles the playlist window
#define WINAMP_HELP_ABOUT 40041 // pops up the about box :)
#define WINAMP_MAINMENU 40043
/* the following are the five main control buttons, with optionally shift
** or control pressed
** (for the exact functions of each, just try it out)
*/
#define WINAMP_BUTTON1 40044
#define WINAMP_BUTTON2 40045
#define WINAMP_BUTTON3 40046
#define WINAMP_BUTTON4 40047
#define WINAMP_BUTTON5 40048
#define WINAMP_BUTTON1_SHIFT 40144
#define WINAMP_BUTTON2_SHIFT 40145
#define WINAMP_BUTTON3_SHIFT 40146
#define WINAMP_BUTTON4_SHIFT 40147
#define WINAMP_BUTTON5_SHIFT 40148
#define WINAMP_BUTTON1_CTRL 40154
#define WINAMP_BUTTON2_CTRL 40155
#define WINAMP_BUTTON3_CTRL 40156
#define WINAMP_BUTTON4_CTRL 40157
#define WINAMP_BUTTON5_CTRL 40158
#define WINAMP_VOLUMEUP 40058 // turns the volume up a little
#define WINAMP_VOLUMEDOWN 40059 // turns the volume down a little
#define WINAMP_FFWD5S 40060 // fast forwards 5 seconds
#define WINAMP_REW5S 40061 // rewinds 5 seconds
#define WINAMP_NEXT_WINDOW 40063
#define WINAMP_OPTIONS_WINDOWSHADE 40064
#define WINAMP_OPTIONS_DSIZE 40165
#define IDC_SORT_FILENAME 40166
#define IDC_SORT_FILETITLE 40167
#define IDC_SORT_ENTIREFILENAME 40168
#define IDC_SELECTALL 40169
#define IDC_SELECTNONE 40170
#define IDC_SELECTINV 40171
#define IDM_EQ_LOADPRE 40172
#define IDM_EQ_LOADMP3 40173
#define IDM_EQ_LOADDEFAULT 40174
#define IDM_EQ_SAVEPRE 40175
#define IDM_EQ_SAVEMP3 40176
#define IDM_EQ_SAVEDEFAULT 40177
#define IDM_EQ_DELPRE 40178
#define IDM_EQ_DELMP3 40180
#define IDC_PLAYLIST_PLAY 40184
#define WINAMP_FILE_LOC 40185
#define WINAMP_OPTIONS_EASYMOVE 40186
#define WINAMP_FILE_DIR 40187 // pops up the load directory box
#define WINAMP_EDIT_ID3 40188
#define WINAMP_TOGGLE_AUTOSCROLL 40189
#define WINAMP_VISSETUP 40190
#define WINAMP_PLGSETUP 40191
#define WINAMP_VISPLUGIN 40192
#define WINAMP_JUMP 40193
#define WINAMP_JUMPFILE 40194
#define WINAMP_JUMP10FWD 40195
#define WINAMP_JUMP10BACK 40197
#define WINAMP_PREVSONG 40198
#define WINAMP_OPTIONS_EXTRAHQ 40200
#define ID_PE_NEW 40201
#define ID_PE_OPEN 40202
#define ID_PE_SAVE 40203
#define ID_PE_SAVEAS 40204
#define ID_PE_SELECTALL 40205
#define ID_PE_INVERT 40206
#define ID_PE_NONE 40207
#define ID_PE_ID3 40208
#define ID_PE_S_TITLE 40209
#define ID_PE_S_FILENAME 40210
#define ID_PE_S_PATH 40211
#define ID_PE_S_RANDOM 40212
#define ID_PE_S_REV 40213
#define ID_PE_CLEAR 40214
#define ID_PE_MOVEUP 40215
#define ID_PE_MOVEDOWN 40216
#define WINAMP_SELSKIN 40219
#define WINAMP_VISCONF 40221
#define ID_PE_NONEXIST 40222
#define ID_PE_DELETEFROMDISK 40223
#define ID_PE_CLOSE 40224
#define WINAMP_VIS_SETOSC 40226
#define WINAMP_VIS_SETANA 40227
#define WINAMP_VIS_SETOFF 40228
#define WINAMP_VIS_DOTSCOPE 40229
#define WINAMP_VIS_LINESCOPE 40230
#define WINAMP_VIS_SOLIDSCOPE 40231
#define WINAMP_VIS_NORMANA 40233
#define WINAMP_VIS_FIREANA 40234
#define WINAMP_VIS_LINEANA 40235
#define WINAMP_VIS_NORMVU 40236
#define WINAMP_VIS_SMOOTHVU 40237
#define WINAMP_VIS_FULLREF 40238
#define WINAMP_VIS_FULLREF2 40239
#define WINAMP_VIS_FULLREF3 40240
#define WINAMP_VIS_FULLREF4 40241
#define WINAMP_OPTIONS_TOGTIME 40242
#define EQ_ENABLE 40244
#define EQ_AUTO 40245
#define EQ_PRESETS 40246
#define WINAMP_VIS_FALLOFF0 40247
#define WINAMP_VIS_FALLOFF1 40248
#define WINAMP_VIS_FALLOFF2 40249
#define WINAMP_VIS_FALLOFF3 40250
#define WINAMP_VIS_FALLOFF4 40251
#define WINAMP_VIS_PEAKS 40252
#define ID_LOAD_EQF 40253
#define ID_SAVE_EQF 40254
#define ID_PE_ENTRY 40255
#define ID_PE_SCROLLUP 40256
#define ID_PE_SCROLLDOWN 40257
#define WINAMP_MAIN_WINDOW 40258
#define WINAMP_VIS_PFALLOFF0 40259
#define WINAMP_VIS_PFALLOFF1 40260
#define WINAMP_VIS_PFALLOFF2 40261
#define WINAMP_VIS_PFALLOFF3 40262
#define WINAMP_VIS_PFALLOFF4 40263
#define ID_PE_TOP 40264
#define ID_PE_BOTTOM 40265
#define WINAMP_OPTIONS_WINDOWSHADE_PL 40266
#define EQ_INC1 40267
#define EQ_INC2 40268
#define EQ_INC3 40269
#define EQ_INC4 40270
#define EQ_INC5 40271
#define EQ_INC6 40272
#define EQ_INC7 40273
#define EQ_INC8 40274
#define EQ_INC9 40275
#define EQ_INC10 40276
#define EQ_INCPRE 40277
#define EQ_DECPRE 40278
#define EQ_DEC1 40279
#define EQ_DEC2 40280
#define EQ_DEC3 40281
#define EQ_DEC4 40282
#define EQ_DEC5 40283
#define EQ_DEC6 40284
#define EQ_DEC7 40285
#define EQ_DEC8 40286
#define EQ_DEC9 40287
#define EQ_DEC10 40288
#define ID_PE_SCUP 40289
#define ID_PE_SCDOWN 40290
#define WINAMP_REFRESHSKIN 40291
#define ID_PE_PRINT 40292
#define ID_PE_EXTINFO 40293
#define WINAMP_PLAYLIST_ADVANCE 40294
#define WINAMP_VIS_LIN 40295
#define WINAMP_VIS_BAR 40296
#define WINAMP_OPTIONS_MINIBROWSER 40298
#define MB_FWD 40299
#define MB_BACK 40300
#define MB_RELOAD 40301
#define MB_OPENMENU 40302
#define MB_OPENLOC 40303
#define WINAMP_NEW_INSTANCE 40305
#define MB_UPDATE 40309
#define WINAMP_OPTIONS_WINDOWSHADE_EQ 40310
#define EQ_PANLEFT 40313
#define EQ_PANRIGHT 40314
#define WINAMP_GETMORESKINS 40316
#define WINAMP_VIS_OPTIONS 40317
#define WINAMP_PE_SEARCH 40318
#define ID_PE_BOOKMARK 40319
#define WINAMP_EDIT_BOOKMARKS 40320
#define WINAMP_MAKECURBOOKMARK 40321
#define ID_MAIN_PLAY_BOOKMARK_NONE 40322
#define ID_MAIN_PLAY_AUDIOCD 40323 // starts playing the audio CD in the first CD reader
#define ID_MAIN_PLAY_AUDIOCD2 40324 // plays the 2nd
#define ID_MAIN_PLAY_AUDIOCD3 40325 // plays the 3rd
#define ID_MAIN_PLAY_AUDIOCD4 40326 // plays the 4th
#define WINAMP_OPTIONS_VIDEO 40328
#define ID_VIDEOWND_ZOOMFULLSCREEN 40329
#define ID_VIDEOWND_ZOOM100 40330
#define ID_VIDEOWND_ZOOM200 40331
#define ID_VIDEOWND_ZOOM50 40332
#define ID_VIDEOWND_VIDEOOPTIONS 40333
#define WINAMP_MINIMIZE 40334
#define ID_PE_FONTBIGGER 40335
#define ID_PE_FONTSMALLER 40336
#define WINAMP_VIDEO_TOGGLE_FS 40337
#define WINAMP_VIDEO_TVBUTTON 40338
#define WINAMP_LIGHTNING_CLICK 40339
#define ID_FILE_ADDTOLIBRARY 40344
#define ID_HELP_HELPTOPICS 40347
#define ID_HELP_GETTINGSTARTED 40348
#define ID_HELP_WINAMPFORUMS 40349
#define ID_PLAY_VOLUMEUP 40351
#define ID_PLAY_VOLUMEDOWN 40352
#define ID_PEFILE_OPENPLAYLISTFROMLIBRARY_NOPLAYLISTSINLIBRARY 40355
#define ID_PEFILE_ADDFROMLIBRARY 40356
#define ID_PEFILE_CLOSEPLAYLISTEDITOR 40357
#define ID_PEPLAYLIST_PLAYLISTPREFERENCES 40358
#define ID_MLFILE_NEWPLAYLIST 40359
#define ID_MLFILE_LOADPLAYLIST 40360
#define ID_MLFILE_SAVEPLAYLIST 40361
#define ID_MLFILE_ADDMEDIATOLIBRARY 40362
#define ID_MLFILE_CLOSEMEDIALIBRARY 40363
#define ID_MLVIEW_NOWPLAYING 40364
#define ID_MLVIEW_LOCALMEDIA_ALLMEDIA 40366
#define ID_MLVIEW_LOCALMEDIA_AUDIO 40367
#define ID_MLVIEW_LOCALMEDIA_VIDEO 40368
#define ID_MLVIEW_PLAYLISTS_NOPLAYLISTINLIBRARY 40369
#define ID_MLVIEW_INTERNETRADIO 40370
#define ID_MLVIEW_INTERNETTV 40371
#define ID_MLVIEW_LIBRARYPREFERENCES 40372
#define ID_MLVIEW_DEVICES_NOAVAILABLEDEVICE 40373
#define ID_MLFILE_IMPORTCURRENTPLAYLIST 40374
#define ID_MLVIEW_MEDIA 40376
#define ID_MLVIEW_PLAYLISTS 40377
#define ID_MLVIEW_MEDIA_ALLMEDIA 40377
#define ID_MLVIEW_DEVICES 40378
#define ID_FILE_SHOWLIBRARY 40379
#define ID_FILE_CLOSELIBRARY 40380
#define ID_POST_PLAY_PLAYLIST 40381
#define ID_VIS_NEXT 40382
#define ID_VIS_PREV 40383
#define ID_VIS_RANDOM 40384
#define ID_MANAGEPLAYLISTS 40385
#define ID_PREFS_SKIN_SWITCHTOSKIN 40386
#define ID_PREFS_SKIN_DELETESKIN 40387
#define ID_PREFS_SKIN_RENAMESKIN 40388
#define ID_VIS_FS 40389
#define ID_VIS_CFG 40390
#define ID_VIS_MENU 40391
#define ID_VIS_SET_FS_FLAG 40392
#define ID_PE_SHOWPLAYING 40393
#define ID_HELP_REGISTERWINAMPPRO 40394
#define ID_PE_MANUAL_ADVANCE 40395
#define WA_SONG_5_STAR_RATING 40396
#define WA_SONG_4_STAR_RATING 40397
#define WA_SONG_3_STAR_RATING 40398
#define WA_SONG_2_STAR_RATING 40399
#define WA_SONG_1_STAR_RATING 40400
#define WA_SONG_NO_RATING 40401
#define PL_SONG_5_STAR_RATING 40402
#define PL_SONG_4_STAR_RATING 40403
#define PL_SONG_3_STAR_RATING 40404
#define PL_SONG_2_STAR_RATING 40405
#define PL_SONG_1_STAR_RATING 40406
#define PL_SONG_NO_RATING 40407
#define AUDIO_TRACK_ONE 40408
#define VIDEO_TRACK_ONE 40424
#define ID_SWITCH_COLOURTHEME 44500
#define ID_GENFF_LIMIT 45000
#endif
+236
View File
@@ -0,0 +1,236 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Global.h"
#include "Font.h"
#include "InputPlugin.h"
#include "OutputPlugin.h"
#include "VisPlugin.h"
#include "DspPlugin.h"
#include "GenPlugin.h"
#include "Main.h"
#include "Rebar.h"
#include "Playlist.h"
#include "Status.h"
#include "PluginManager.h"
#include "Prefs.h"
#include "Config.h"
#include "Emabox/Emabox.h"
#define PLUS_ALT ( FVIRTKEY | FALT )
#define PLUS_CONTROL ( FVIRTKEY | FCONTROL )
#define PLUS_CONTROL_ALT ( FVIRTKEY | FCONTROL | FALT )
#define PLUS_CONTROL_SHIFT ( FVIRTKEY | FCONTROL | FSHIFT )
#define PLUS_SHIFT ( FVIRTKEY | FSHIFT )
HINSTANCE g_hInstance = NULL; // extern
TCHAR * szHomeDir = NULL; // extern
int iHomeDirLen = 0; // extern
TCHAR * szPluginDir = NULL; // extern
int iPluginDirLen = 0; // extern
TCHAR szCurDir[ MAX_PATH + 1 ] = TEXT( "" );
ConfCurDir ccdCurDir( szCurDir, TEXT( "CurDir" ) );
bool bWarnPluginsMissing;
ConfBool cbWarnPluginsMissing( &bWarnPluginsMissing, TEXT( "WarnPluginsMissing" ), CONF_MODE_PUBLIC, true );
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow )
{
g_hInstance = hInstance;
// Load full config
Conf::Init( hInstance );
// Get home dir
szHomeDir = new TCHAR[ MAX_PATH + 1 ];
iHomeDirLen = GetModuleFileName( NULL, szHomeDir, MAX_PATH );
if( !iHomeDirLen ) return 1;
TCHAR * walk = szHomeDir + iHomeDirLen - 1;
while( ( walk > szHomeDir ) && ( *walk != TEXT( '\\' ) ) ) walk--;
walk++;
*walk = TEXT( '\0' );
iHomeDirLen = walk - szHomeDir;
// Get plugins dir
szPluginDir = new TCHAR[ MAX_PATH + 1 ];
memcpy( szPluginDir, szHomeDir, iHomeDirLen * sizeof( TCHAR ) );
memcpy( szPluginDir + iHomeDirLen, TEXT( "Plugins" ), 7 * sizeof( TCHAR ) );
szPluginDir[ iHomeDirLen + 7 ] = TEXT( '\0' );
Font::Create();
BuildMainWindow();
Prefs::Create();
// Show window
ShowWindow( WindowMain, SW_SHOW );
SetForegroundWindow( WindowMain );
SetFocus( WindowMain );
Plugin::FindAll<InputPlugin> ( szPluginDir, TEXT( "in_*.dll" ), true );
Plugin::FindAll<OutputPlugin>( szPluginDir, TEXT( "out_*.dll" ), false );
Plugin::FindAll<VisPlugin> ( szPluginDir, TEXT( "vis_*.dll" ), false );
Plugin::FindAll<DspPlugin> ( szPluginDir, TEXT( "dsp_*.dll" ), false );
Plugin::FindAll<GenPlugin> ( szPluginDir, TEXT( "gen_*.dll" ), true );
PluginManager::Fill();
// Check plugin presence
// One msgbox maximum
if( bWarnPluginsMissing )
{
if( input_plugins.empty() )
{
// No input plugins
TCHAR szBuffer[ 5000 ];
_stprintf(
szBuffer,
TEXT(
"No input plugins were found.\n"
"\n"
"Please install at least one Winamp input plugin to \n"
"%s "
),
szPluginDir
);
int iNeverAgain = bWarnPluginsMissing ? 0 : 1;
EmaBox( 0, szBuffer, TEXT( "Input plugins missing" ), MB_ICONEXCLAMATION | MB_CHECKNEVERAGAIN, &iNeverAgain );
bWarnPluginsMissing = ( iNeverAgain == 0 );
}
else if( output_plugins.empty() )
{
// No output plugins
TCHAR szBuffer[ 5000 ];
_stprintf(
szBuffer,
TEXT(
"No output plugins were found.\n"
"\n"
"Please install at least one Winamp output plugin to \n"
"%s "
),
szPluginDir
);
int iNeverAgain = bWarnPluginsMissing ? 0 : 1;
EmaBox( 0, szBuffer, TEXT( "Output plugins missing" ), MB_ICONEXCLAMATION | MB_CHECKNEVERAGAIN, &iNeverAgain );
bWarnPluginsMissing = ( iNeverAgain == 0 );
}
}
// Todo: all the rest...
ACCEL accels[] = {
{ PLUS_CONTROL, 'A', ID_PE_SELECTALL }, // [Ctrl] + [A]
{ PLUS_CONTROL, 'I', ID_PE_INVERT }, // [Ctrl] + [I]
{ PLUS_CONTROL, 'N', ID_PE_NEW }, // [Ctrl] + [N]
{ PLUS_CONTROL, 'O', ID_PE_OPEN }, // [Ctrl] + [O]
{ PLUS_CONTROL, 'P', WINAMP_OPTIONS_PREFS }, // [Ctrl] + [P]
{ PLUS_CONTROL, 'S', ID_PE_SAVEAS }, // [Ctrl] + [S]
{ PLUS_CONTROL, VK_F1, WINAMP_HELP_ABOUT }, // [Ctrl] + [F1]
{ PLUS_CONTROL_SHIFT, 'A', ID_PE_NONE }, // [Ctrl] + [Shift] + [A]
{ PLUS_CONTROL_SHIFT, VK_DELETE, ID_PE_CLEAR }, // [Ctrl] + [Shift] + [Del]
{ PLUS_ALT, 'F', WINAMP_MAINMENU }, // [Alt] + [F]
{ PLUS_ALT, VK_F4, WINAMP_FILE_QUIT } // [Alt] + [F4]
};
HACCEL hAccel = CreateAcceleratorTable( accels, sizeof( accels ) / sizeof( ACCEL ) );
if( !hAccel )
{
MessageBox( 0, TEXT( "Accelerator table error" ), TEXT( "" ), 0 );
}
// Message loop
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) > 0 )
{
// Note: Keys without [Alt] or [Ctrl] not everywhere!
if( ( ( msg.hwnd == WindowMain ) || IsChild( WindowMain, msg.hwnd ) ) &&
TranslateAccelerator( WindowMain, hAccel, &msg ) )
{
// MessageBox( 0, TEXT( "Trans" ), TEXT( "" ), 0 );
}
TranslateMessage( &msg );
DispatchMessage( &msg );
}
DestroyAcceleratorTable( hAccel );
// Input
vector <InputPlugin *>::iterator iter_input = input_plugins.begin();
while( iter_input != input_plugins.end() )
{
( *iter_input )->Unload();
iter_input++;
}
// Output
vector <OutputPlugin *>::iterator iter_output = output_plugins.begin();
while( iter_output != output_plugins.end() )
{
( *iter_output )->Unload();
iter_output++;
}
// General
vector <GenPlugin *>::iterator iter_gen = gen_plugins.begin();
while( iter_gen != gen_plugins.end() )
{
( *iter_gen )->Unload();
iter_gen++;
}
// TODO: create main::destroy
// UnregisterClass( PA_CLASSNAME, g_hInstance );
Prefs::Destroy();
Font::Destroy();
/*
delete [] szPluginDir;
delete [] szHomeDir;
*/
Conf::Write();
return 0;
}
+823
View File
@@ -0,0 +1,823 @@
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#ifndef __AFXRES_H__
#define __AFXRES_H__
#ifdef RC_INVOKED
#ifndef _INC_WINDOWS
#define _INC_WINDOWS
#include "winres.h" // extract from windows header
#endif
#endif
#ifdef _AFX_MINREBUILD
#pragma component(minrebuild, off)
#endif
#ifdef RC_INVOKED
#if defined(_VC80_UPGRADE) && (_VC80_UPGRADE >= 0x0700) && (_VC80_UPGRADE < 0x0800) && defined(IDR_MANIFEST)
// Handle project upgrade from VC7/VC7.1 for projects with manifest
#define IDR_MANIFEST 1024
#endif
#endif // RC_INVOKED
#ifdef APSTUDIO_INVOKED
#define APSTUDIO_HIDDEN_SYMBOLS
#endif
/////////////////////////////////////////////////////////////////////////////
// MFC resource types (see Technical note TN024 for implementation details)
#ifndef RC_INVOKED
#define RT_DLGINIT MAKEINTRESOURCE(240)
#define RT_TOOLBAR MAKEINTRESOURCE(241)
#endif
/////////////////////////////////////////////////////////////////////////////
#ifdef APSTUDIO_INVOKED
#undef APSTUDIO_HIDDEN_SYMBOLS
#endif
/////////////////////////////////////////////////////////////////////////////
// General style bits etc
// ControlBar styles
#define CBRS_ALIGN_LEFT 0x1000L
#define CBRS_ALIGN_TOP 0x2000L
#define CBRS_ALIGN_RIGHT 0x4000L
#define CBRS_ALIGN_BOTTOM 0x8000L
#define CBRS_ALIGN_ANY 0xF000L
#define CBRS_BORDER_LEFT 0x0100L
#define CBRS_BORDER_TOP 0x0200L
#define CBRS_BORDER_RIGHT 0x0400L
#define CBRS_BORDER_BOTTOM 0x0800L
#define CBRS_BORDER_ANY 0x0F00L
#define CBRS_TOOLTIPS 0x0010L
#define CBRS_FLYBY 0x0020L
#define CBRS_FLOAT_MULTI 0x0040L
#define CBRS_BORDER_3D 0x0080L
#define CBRS_HIDE_INPLACE 0x0008L
#define CBRS_SIZE_DYNAMIC 0x0004L
#define CBRS_SIZE_FIXED 0x0002L
#define CBRS_FLOATING 0x0001L
#define CBRS_GRIPPER 0x00400000L
#define CBRS_ORIENT_HORZ (CBRS_ALIGN_TOP|CBRS_ALIGN_BOTTOM)
#define CBRS_ORIENT_VERT (CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT)
#define CBRS_ORIENT_ANY (CBRS_ORIENT_HORZ|CBRS_ORIENT_VERT)
#define CBRS_ALL 0x0040FFFFL
// the CBRS_ style is made up of an alignment style and a draw border style
// the alignment styles are mutually exclusive
// the draw border styles may be combined
#define CBRS_NOALIGN 0x00000000L
#define CBRS_LEFT (CBRS_ALIGN_LEFT|CBRS_BORDER_RIGHT)
#define CBRS_TOP (CBRS_ALIGN_TOP|CBRS_BORDER_BOTTOM)
#define CBRS_RIGHT (CBRS_ALIGN_RIGHT|CBRS_BORDER_LEFT)
#define CBRS_BOTTOM (CBRS_ALIGN_BOTTOM|CBRS_BORDER_TOP)
/////////////////////////////////////////////////////////////////////////////
// Manifest Resource ID of manifest containing Localized DLL information
#define ID_MFCLOC_MANIFEST 1000
/////////////////////////////////////////////////////////////////////////////
// Standard window components
// Mode indicators in status bar - these are routed like commands
#define ID_INDICATOR_EXT 0xE700 // extended selection indicator
#define ID_INDICATOR_CAPS 0xE701 // cap lock indicator
#define ID_INDICATOR_NUM 0xE702 // num lock indicator
#define ID_INDICATOR_SCRL 0xE703 // scroll lock indicator
#define ID_INDICATOR_OVR 0xE704 // overtype mode indicator
#define ID_INDICATOR_REC 0xE705 // record mode indicator
#define ID_INDICATOR_KANA 0xE706 // kana lock indicator
#define ID_SEPARATOR 0 // special separator value
#ifndef RC_INVOKED // code only
// Standard control bars (IDW = window ID)
#define AFX_IDW_CONTROLBAR_FIRST 0xE800
#define AFX_IDW_CONTROLBAR_LAST 0xE8FF
#define AFX_IDW_TOOLBAR 0xE800 // main Toolbar for window
#define AFX_IDW_STATUS_BAR 0xE801 // Status bar window
#define AFX_IDW_PREVIEW_BAR 0xE802 // PrintPreview Dialog Bar
#define AFX_IDW_RESIZE_BAR 0xE803 // OLE in-place resize bar
#define AFX_IDW_REBAR 0xE804 // COMCTL32 "rebar" Bar
#define AFX_IDW_DIALOGBAR 0xE805 // CDialogBar
// Note: If your application supports docking toolbars, you should
// not use the following IDs for your own toolbars. The IDs chosen
// are at the top of the first 32 such that the bars will be hidden
// while in print preview mode, and are not likely to conflict with
// IDs your application may have used succesfully in the past.
#define AFX_IDW_DOCKBAR_TOP 0xE81B
#define AFX_IDW_DOCKBAR_LEFT 0xE81C
#define AFX_IDW_DOCKBAR_RIGHT 0xE81D
#define AFX_IDW_DOCKBAR_BOTTOM 0xE81E
#define AFX_IDW_DOCKBAR_FLOAT 0xE81F
// Macro for mapping standard control bars to bitmask (limit of 32)
#define AFX_CONTROLBAR_MASK(nIDC) (1L << (nIDC - AFX_IDW_CONTROLBAR_FIRST))
// parts of Main Frame
#define AFX_IDW_PANE_FIRST 0xE900 // first pane (256 max)
#define AFX_IDW_PANE_LAST 0xE9ff
#define AFX_IDW_HSCROLL_FIRST 0xEA00 // first Horz scrollbar (16 max)
#define AFX_IDW_VSCROLL_FIRST 0xEA10 // first Vert scrollbar (16 max)
#define AFX_IDW_SIZE_BOX 0xEA20 // size box for splitters
#define AFX_IDW_PANE_SAVE 0xEA21 // to shift AFX_IDW_PANE_FIRST
#endif //!RC_INVOKED
#ifndef APSTUDIO_INVOKED
// common style for form views
#define AFX_WS_DEFAULT_VIEW (WS_CHILD | WS_VISIBLE | WS_BORDER)
#endif //!APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Standard app configurable strings
// for application title (defaults to EXE name or name in constructor)
#define AFX_IDS_APP_TITLE 0xE000
// idle message bar line
#define AFX_IDS_IDLEMESSAGE 0xE001
// message bar line when in shift-F1 help mode
#define AFX_IDS_HELPMODEMESSAGE 0xE002
// document title when editing OLE embedding
#define AFX_IDS_APP_TITLE_EMBEDDING 0xE003
// company name
#define AFX_IDS_COMPANY_NAME 0xE004
// object name when server is inplace
#define AFX_IDS_OBJ_TITLE_INPLACE 0xE005
/////////////////////////////////////////////////////////////////////////////
// Standard Commands
// File commands
#define ID_FILE_NEW 0xE100
#define ID_FILE_OPEN 0xE101
#define ID_FILE_CLOSE 0xE102
#define ID_FILE_SAVE 0xE103
#define ID_FILE_SAVE_AS 0xE104
#define ID_FILE_PAGE_SETUP 0xE105
#define ID_FILE_PRINT_SETUP 0xE106
#define ID_FILE_PRINT 0xE107
#define ID_FILE_PRINT_DIRECT 0xE108
#define ID_FILE_PRINT_PREVIEW 0xE109
#define ID_FILE_UPDATE 0xE10A
#define ID_FILE_SAVE_COPY_AS 0xE10B
#define ID_FILE_SEND_MAIL 0xE10C
#define ID_FILE_NEW_FRAME 0xE10D
#define ID_FILE_MRU_FIRST 0xE110
#define ID_FILE_MRU_FILE1 0xE110 // range - 16 max
#define ID_FILE_MRU_FILE2 0xE111
#define ID_FILE_MRU_FILE3 0xE112
#define ID_FILE_MRU_FILE4 0xE113
#define ID_FILE_MRU_FILE5 0xE114
#define ID_FILE_MRU_FILE6 0xE115
#define ID_FILE_MRU_FILE7 0xE116
#define ID_FILE_MRU_FILE8 0xE117
#define ID_FILE_MRU_FILE9 0xE118
#define ID_FILE_MRU_FILE10 0xE119
#define ID_FILE_MRU_FILE11 0xE11A
#define ID_FILE_MRU_FILE12 0xE11B
#define ID_FILE_MRU_FILE13 0xE11C
#define ID_FILE_MRU_FILE14 0xE11D
#define ID_FILE_MRU_FILE15 0xE11E
#define ID_FILE_MRU_FILE16 0xE11F
#define ID_FILE_MRU_LAST 0xE11F
// Edit commands
#define ID_EDIT_CLEAR 0xE120
#define ID_EDIT_CLEAR_ALL 0xE121
#define ID_EDIT_COPY 0xE122
#define ID_EDIT_CUT 0xE123
#define ID_EDIT_FIND 0xE124
#define ID_EDIT_PASTE 0xE125
#define ID_EDIT_PASTE_LINK 0xE126
#define ID_EDIT_PASTE_SPECIAL 0xE127
#define ID_EDIT_REPEAT 0xE128
#define ID_EDIT_REPLACE 0xE129
#define ID_EDIT_SELECT_ALL 0xE12A
#define ID_EDIT_UNDO 0xE12B
#define ID_EDIT_REDO 0xE12C
// Window commands
#define ID_WINDOW_NEW 0xE130
#define ID_WINDOW_ARRANGE 0xE131
#define ID_WINDOW_CASCADE 0xE132
#define ID_WINDOW_TILE_HORZ 0xE133
#define ID_WINDOW_TILE_VERT 0xE134
#define ID_WINDOW_SPLIT 0xE135
#ifndef RC_INVOKED // code only
#define AFX_IDM_WINDOW_FIRST 0xE130
#define AFX_IDM_WINDOW_LAST 0xE13F
#define AFX_IDM_FIRST_MDICHILD 0xFF00 // window list starts here
#endif //!RC_INVOKED
// Help and App commands
#define ID_APP_ABOUT 0xE140
#define ID_APP_EXIT 0xE141
#define ID_HELP_INDEX 0xE142
#define ID_HELP_FINDER 0xE143
#define ID_HELP_USING 0xE144
#define ID_CONTEXT_HELP 0xE145 // shift-F1
// special commands for processing help
#define ID_HELP 0xE146 // first attempt for F1
#define ID_DEFAULT_HELP 0xE147 // last attempt
// Misc
#define ID_NEXT_PANE 0xE150
#define ID_PREV_PANE 0xE151
// Format
#define ID_FORMAT_FONT 0xE160
// OLE commands
#define ID_OLE_INSERT_NEW 0xE200
#define ID_OLE_EDIT_LINKS 0xE201
#define ID_OLE_EDIT_CONVERT 0xE202
#define ID_OLE_EDIT_CHANGE_ICON 0xE203
#define ID_OLE_EDIT_PROPERTIES 0xE204
#define ID_OLE_VERB_FIRST 0xE210 // range - 16 max
#ifndef RC_INVOKED // code only
#define ID_OLE_VERB_LAST 0xE21F
#endif //!RC_INVOKED
// for print preview dialog bar
#define AFX_ID_PREVIEW_CLOSE 0xE300
#define AFX_ID_PREVIEW_NUMPAGE 0xE301 // One/Two Page button
#define AFX_ID_PREVIEW_NEXT 0xE302
#define AFX_ID_PREVIEW_PREV 0xE303
#define AFX_ID_PREVIEW_PRINT 0xE304
#define AFX_ID_PREVIEW_ZOOMIN 0xE305
#define AFX_ID_PREVIEW_ZOOMOUT 0xE306
// View commands (same number used as IDW used for control bar)
#define ID_VIEW_TOOLBAR 0xE800
#define ID_VIEW_STATUS_BAR 0xE801
#define ID_VIEW_REBAR 0xE804
#define ID_VIEW_AUTOARRANGE 0xE805
// E810 -> E81F must be kept in order for RANGE macros
#define ID_VIEW_SMALLICON 0xE810
#define ID_VIEW_LARGEICON 0xE811
#define ID_VIEW_LIST 0xE812
#define ID_VIEW_DETAILS 0xE813
#define ID_VIEW_LINEUP 0xE814
#define ID_VIEW_BYNAME 0xE815
#define AFX_ID_VIEW_MINIMUM ID_VIEW_SMALLICON
#define AFX_ID_VIEW_MAXIMUM ID_VIEW_BYNAME
// E800 -> E8FF reserved for other control bar commands
// RecordForm commands
#define ID_RECORD_FIRST 0xE900
#define ID_RECORD_LAST 0xE901
#define ID_RECORD_NEXT 0xE902
#define ID_RECORD_PREV 0xE903
/////////////////////////////////////////////////////////////////////////////
// Standard control IDs
#ifdef IDC_STATIC
#undef IDC_STATIC
#endif
#define IDC_STATIC (-1) // all static controls
/////////////////////////////////////////////////////////////////////////////
// Standard string error/warnings
#ifndef RC_INVOKED // code only
#define AFX_IDS_SCFIRST 0xEF00
#endif //!RC_INVOKED
#define AFX_IDS_SCSIZE 0xEF00
#define AFX_IDS_SCMOVE 0xEF01
#define AFX_IDS_SCMINIMIZE 0xEF02
#define AFX_IDS_SCMAXIMIZE 0xEF03
#define AFX_IDS_SCNEXTWINDOW 0xEF04
#define AFX_IDS_SCPREVWINDOW 0xEF05
#define AFX_IDS_SCCLOSE 0xEF06
#define AFX_IDS_SCRESTORE 0xEF12
#define AFX_IDS_SCTASKLIST 0xEF13
#define AFX_IDS_MDICHILD 0xEF1F
#define AFX_IDS_DESKACCESSORY 0xEFDA
// General strings
#define AFX_IDS_OPENFILE 0xF000
#define AFX_IDS_SAVEFILE 0xF001
#define AFX_IDS_ALLFILTER 0xF002
#define AFX_IDS_UNTITLED 0xF003
#define AFX_IDS_SAVEFILECOPY 0xF004
#define AFX_IDS_PREVIEW_CLOSE 0xF005
#define AFX_IDS_UNNAMED_FILE 0xF006
#define AFX_IDS_HIDE 0xF011
// MFC Standard Exception Error messages
#define AFX_IDP_NO_ERROR_AVAILABLE 0xF020
#define AFX_IDS_NOT_SUPPORTED_EXCEPTION 0xF021
#define AFX_IDS_RESOURCE_EXCEPTION 0xF022
#define AFX_IDS_MEMORY_EXCEPTION 0xF023
#define AFX_IDS_USER_EXCEPTION 0xF024
#define AFX_IDS_INVALID_ARG_EXCEPTION 0xF025
// Printing and print preview strings
#define AFX_IDS_PRINTONPORT 0xF040
#define AFX_IDS_ONEPAGE 0xF041
#define AFX_IDS_TWOPAGE 0xF042
#define AFX_IDS_PRINTPAGENUM 0xF043
#define AFX_IDS_PREVIEWPAGEDESC 0xF044
#define AFX_IDS_PRINTDEFAULTEXT 0xF045
#define AFX_IDS_PRINTDEFAULT 0xF046
#define AFX_IDS_PRINTFILTER 0xF047
#define AFX_IDS_PRINTCAPTION 0xF048
#define AFX_IDS_PRINTTOFILE 0xF049
// OLE strings
#define AFX_IDS_OBJECT_MENUITEM 0xF080
#define AFX_IDS_EDIT_VERB 0xF081
#define AFX_IDS_ACTIVATE_VERB 0xF082
#define AFX_IDS_CHANGE_LINK 0xF083
#define AFX_IDS_AUTO 0xF084
#define AFX_IDS_MANUAL 0xF085
#define AFX_IDS_FROZEN 0xF086
#define AFX_IDS_ALL_FILES 0xF087
// dynamically changing menu items
#define AFX_IDS_SAVE_MENU 0xF088
#define AFX_IDS_UPDATE_MENU 0xF089
#define AFX_IDS_SAVE_AS_MENU 0xF08A
#define AFX_IDS_SAVE_COPY_AS_MENU 0xF08B
#define AFX_IDS_EXIT_MENU 0xF08C
#define AFX_IDS_UPDATING_ITEMS 0xF08D
// COlePasteSpecialDialog defines
#define AFX_IDS_METAFILE_FORMAT 0xF08E
#define AFX_IDS_DIB_FORMAT 0xF08F
#define AFX_IDS_BITMAP_FORMAT 0xF090
#define AFX_IDS_LINKSOURCE_FORMAT 0xF091
#define AFX_IDS_EMBED_FORMAT 0xF092
// other OLE utility strings
#define AFX_IDS_PASTELINKEDTYPE 0xF094
#define AFX_IDS_UNKNOWNTYPE 0xF095
#define AFX_IDS_RTF_FORMAT 0xF096
#define AFX_IDS_TEXT_FORMAT 0xF097
// OLE datatype format error strings
#define AFX_IDS_INVALID_CURRENCY 0xF098
#define AFX_IDS_INVALID_DATETIME 0xF099
#define AFX_IDS_INVALID_DATETIMESPAN 0xF09A
// General error / prompt strings
#define AFX_IDP_INVALID_FILENAME 0xF100
#define AFX_IDP_FAILED_TO_OPEN_DOC 0xF101
#define AFX_IDP_FAILED_TO_SAVE_DOC 0xF102
#define AFX_IDP_ASK_TO_SAVE 0xF103
#define AFX_IDP_FAILED_TO_CREATE_DOC 0xF104
#define AFX_IDP_FILE_TOO_LARGE 0xF105
#define AFX_IDP_FAILED_TO_START_PRINT 0xF106
#define AFX_IDP_FAILED_TO_LAUNCH_HELP 0xF107
#define AFX_IDP_INTERNAL_FAILURE 0xF108 // general failure
#define AFX_IDP_COMMAND_FAILURE 0xF109 // command failure
#define AFX_IDP_FAILED_MEMORY_ALLOC 0xF10A
#define AFX_IDP_UNREG_DONE 0xF10B
#define AFX_IDP_UNREG_FAILURE 0xF10C
#define AFX_IDP_DLL_LOAD_FAILED 0xF10D
#define AFX_IDP_DLL_BAD_VERSION 0xF10E
// DDV parse errors
#define AFX_IDP_PARSE_INT 0xF110
#define AFX_IDP_PARSE_REAL 0xF111
#define AFX_IDP_PARSE_INT_RANGE 0xF112
#define AFX_IDP_PARSE_REAL_RANGE 0xF113
#define AFX_IDP_PARSE_STRING_SIZE 0xF114
#define AFX_IDP_PARSE_RADIO_BUTTON 0xF115
#define AFX_IDP_PARSE_BYTE 0xF116
#define AFX_IDP_PARSE_UINT 0xF117
#define AFX_IDP_PARSE_DATETIME 0xF118
#define AFX_IDP_PARSE_CURRENCY 0xF119
#define AFX_IDP_PARSE_GUID 0xF11A
#define AFX_IDP_PARSE_TIME 0xF11B
#define AFX_IDP_PARSE_DATE 0xF11C
// CFile/CArchive error strings for user failure
#define AFX_IDP_FAILED_INVALID_FORMAT 0xF120
#define AFX_IDP_FAILED_INVALID_PATH 0xF121
#define AFX_IDP_FAILED_DISK_FULL 0xF122
#define AFX_IDP_FAILED_ACCESS_READ 0xF123
#define AFX_IDP_FAILED_ACCESS_WRITE 0xF124
#define AFX_IDP_FAILED_IO_ERROR_READ 0xF125
#define AFX_IDP_FAILED_IO_ERROR_WRITE 0xF126
// Script errors / prompt strings
#define AFX_IDP_SCRIPT_ERROR 0xF130
#define AFX_IDP_SCRIPT_DISPATCH_EXCEPTION 0xF131
// OLE errors / prompt strings
#define AFX_IDP_STATIC_OBJECT 0xF180
#define AFX_IDP_FAILED_TO_CONNECT 0xF181
#define AFX_IDP_SERVER_BUSY 0xF182
#define AFX_IDP_BAD_VERB 0xF183
#define AFX_IDS_NOT_DOCOBJECT 0xF184
#define AFX_IDP_FAILED_TO_NOTIFY 0xF185
#define AFX_IDP_FAILED_TO_LAUNCH 0xF186
#define AFX_IDP_ASK_TO_UPDATE 0xF187
#define AFX_IDP_FAILED_TO_UPDATE 0xF188
#define AFX_IDP_FAILED_TO_REGISTER 0xF189
#define AFX_IDP_FAILED_TO_AUTO_REGISTER 0xF18A
#define AFX_IDP_FAILED_TO_CONVERT 0xF18B
#define AFX_IDP_GET_NOT_SUPPORTED 0xF18C
#define AFX_IDP_SET_NOT_SUPPORTED 0xF18D
#define AFX_IDP_ASK_TO_DISCARD 0xF18E
#define AFX_IDP_FAILED_TO_CREATE 0xF18F
// MAPI errors / prompt strings
#define AFX_IDP_FAILED_MAPI_LOAD 0xF190
#define AFX_IDP_INVALID_MAPI_DLL 0xF191
#define AFX_IDP_FAILED_MAPI_SEND 0xF192
#define AFX_IDP_FILE_NONE 0xF1A0
#define AFX_IDP_FILE_GENERIC 0xF1A1
#define AFX_IDP_FILE_NOT_FOUND 0xF1A2
#define AFX_IDP_FILE_BAD_PATH 0xF1A3
#define AFX_IDP_FILE_TOO_MANY_OPEN 0xF1A4
#define AFX_IDP_FILE_ACCESS_DENIED 0xF1A5
#define AFX_IDP_FILE_INVALID_FILE 0xF1A6
#define AFX_IDP_FILE_REMOVE_CURRENT 0xF1A7
#define AFX_IDP_FILE_DIR_FULL 0xF1A8
#define AFX_IDP_FILE_BAD_SEEK 0xF1A9
#define AFX_IDP_FILE_HARD_IO 0xF1AA
#define AFX_IDP_FILE_SHARING 0xF1AB
#define AFX_IDP_FILE_LOCKING 0xF1AC
#define AFX_IDP_FILE_DISKFULL 0xF1AD
#define AFX_IDP_FILE_EOF 0xF1AE
#define AFX_IDP_ARCH_NONE 0xF1B0
#define AFX_IDP_ARCH_GENERIC 0xF1B1
#define AFX_IDP_ARCH_READONLY 0xF1B2
#define AFX_IDP_ARCH_ENDOFFILE 0xF1B3
#define AFX_IDP_ARCH_WRITEONLY 0xF1B4
#define AFX_IDP_ARCH_BADINDEX 0xF1B5
#define AFX_IDP_ARCH_BADCLASS 0xF1B6
#define AFX_IDP_ARCH_BADSCHEMA 0xF1B7
#define AFX_IDS_OCC_SCALEUNITS_PIXELS 0xF1C0
// 0xf200-0xf20f reserved
// font names and point sizes
#define AFX_IDS_STATUS_FONT 0xF230
#define AFX_IDS_TOOLTIP_FONT 0xF231
#define AFX_IDS_UNICODE_FONT 0xF232
#define AFX_IDS_MINI_FONT 0xF233
// ODBC Database errors / prompt strings
#ifndef RC_INVOKED // code only
#define AFX_IDP_SQL_FIRST 0xF280
#endif //!RC_INVOKED
#define AFX_IDP_SQL_CONNECT_FAIL 0xF281
#define AFX_IDP_SQL_RECORDSET_FORWARD_ONLY 0xF282
#define AFX_IDP_SQL_EMPTY_COLUMN_LIST 0xF283
#define AFX_IDP_SQL_FIELD_SCHEMA_MISMATCH 0xF284
#define AFX_IDP_SQL_ILLEGAL_MODE 0xF285
#define AFX_IDP_SQL_MULTIPLE_ROWS_AFFECTED 0xF286
#define AFX_IDP_SQL_NO_CURRENT_RECORD 0xF287
#define AFX_IDP_SQL_NO_ROWS_AFFECTED 0xF288
#define AFX_IDP_SQL_RECORDSET_READONLY 0xF289
#define AFX_IDP_SQL_SQL_NO_TOTAL 0xF28A
#define AFX_IDP_SQL_ODBC_LOAD_FAILED 0xF28B
#define AFX_IDP_SQL_DYNASET_NOT_SUPPORTED 0xF28C
#define AFX_IDP_SQL_SNAPSHOT_NOT_SUPPORTED 0xF28D
#define AFX_IDP_SQL_API_CONFORMANCE 0xF28E
#define AFX_IDP_SQL_SQL_CONFORMANCE 0xF28F
#define AFX_IDP_SQL_NO_DATA_FOUND 0xF290
#define AFX_IDP_SQL_ROW_UPDATE_NOT_SUPPORTED 0xF291
#define AFX_IDP_SQL_ODBC_V2_REQUIRED 0xF292
#define AFX_IDP_SQL_NO_POSITIONED_UPDATES 0xF293
#define AFX_IDP_SQL_LOCK_MODE_NOT_SUPPORTED 0xF294
#define AFX_IDP_SQL_DATA_TRUNCATED 0xF295
#define AFX_IDP_SQL_ROW_FETCH 0xF296
#define AFX_IDP_SQL_INCORRECT_ODBC 0xF297
#define AFX_IDP_SQL_UPDATE_DELETE_FAILED 0xF298
#define AFX_IDP_SQL_DYNAMIC_CURSOR_NOT_SUPPORTED 0xF299
#define AFX_IDP_SQL_FIELD_NOT_FOUND 0xF29A
#define AFX_IDP_SQL_BOOKMARKS_NOT_SUPPORTED 0xF29B
#define AFX_IDP_SQL_BOOKMARKS_NOT_ENABLED 0xF29C
// ODBC Database strings
#define AFX_IDS_DELETED 0xF29D
// DAO Database errors / prompt strings
#ifndef RC_INVOKED // code only
#define AFX_IDP_DAO_FIRST 0xF2B0
#endif //!RC_INVOKED
#define AFX_IDP_DAO_ENGINE_INITIALIZATION 0xF2B0
#define AFX_IDP_DAO_DFX_BIND 0xF2B1
#define AFX_IDP_DAO_OBJECT_NOT_OPEN 0xF2B2
// ICDAORecordset::GetRows Errors
// These are not placed in DAO Errors collection
// and must be handled directly by MFC.
#define AFX_IDP_DAO_ROWTOOSHORT 0xF2B3
#define AFX_IDP_DAO_BADBINDINFO 0xF2B4
#define AFX_IDP_DAO_COLUMNUNAVAILABLE 0xF2B5
/////////////////////////////////////////////////////////////////////////////
// Strings for ISAPI support
#define AFX_IDS_HTTP_TITLE 0xF2D1
#define AFX_IDS_HTTP_NO_TEXT 0xF2D2
#define AFX_IDS_HTTP_BAD_REQUEST 0xF2D3
#define AFX_IDS_HTTP_AUTH_REQUIRED 0xF2D4
#define AFX_IDS_HTTP_FORBIDDEN 0xF2D5
#define AFX_IDS_HTTP_NOT_FOUND 0xF2D6
#define AFX_IDS_HTTP_SERVER_ERROR 0xF2D7
#define AFX_IDS_HTTP_NOT_IMPLEMENTED 0xF2D8
/////////////////////////////////////////////////////////////////////////////
// Strings for Accessibility support for CCheckListBox
#define AFX_IDS_CHECKLISTBOX_UNCHECK 0xF2E1
#define AFX_IDS_CHECKLISTBOX_CHECK 0xF2E2
#define AFX_IDS_CHECKLISTBOX_MIXED 0xF2E3
/////////////////////////////////////////////////////////////////////////////
// AFX implementation - control IDs (AFX_IDC)
// Parts of dialogs
#define AFX_IDC_LISTBOX 100
#define AFX_IDC_CHANGE 101
#define AFX_IDC_BROWSER 102
// for print dialog
#define AFX_IDC_PRINT_DOCNAME 201
#define AFX_IDC_PRINT_PRINTERNAME 202
#define AFX_IDC_PRINT_PORTNAME 203
#define AFX_IDC_PRINT_PAGENUM 204
// Property Sheet control id's (determined with Spy++)
#define ID_APPLY_NOW 0x3021
#define ID_WIZBACK 0x3023
#define ID_WIZNEXT 0x3024
#define ID_WIZFINISH 0x3025
#define AFX_IDC_TAB_CONTROL 0x3020
/////////////////////////////////////////////////////////////////////////////
// IDRs for standard components
#ifndef RC_INVOKED // code only
// These are really COMMDLG dialogs, so there usually isn't a resource
// for them, but these IDs are used as help IDs.
#define AFX_IDD_FILEOPEN 28676
#define AFX_IDD_FILESAVE 28677
#define AFX_IDD_FONT 28678
#define AFX_IDD_COLOR 28679
#define AFX_IDD_PRINT 28680
#define AFX_IDD_PRINTSETUP 28681
#define AFX_IDD_FIND 28682
#define AFX_IDD_REPLACE 28683
#endif //!RC_INVOKED
// Standard dialogs app should leave alone (0x7801->)
#define AFX_IDD_NEWTYPEDLG 30721
#define AFX_IDD_PRINTDLG 30722
#define AFX_IDD_PREVIEW_TOOLBAR 30723
// Dialogs defined for OLE2UI library
#define AFX_IDD_INSERTOBJECT 30724
#define AFX_IDD_CHANGEICON 30725
#define AFX_IDD_CONVERT 30726
#define AFX_IDD_PASTESPECIAL 30727
#define AFX_IDD_EDITLINKS 30728
#define AFX_IDD_FILEBROWSE 30729
#define AFX_IDD_BUSY 30730
#define AFX_IDD_OBJECTPROPERTIES 30732
#define AFX_IDD_CHANGESOURCE 30733
//WinForms
#define AFX_IDD_EMPTYDIALOG 30734
// Standard cursors (0x7901->)
// AFX_IDC = Cursor resources
#define AFX_IDC_CONTEXTHELP 30977 // context sensitive help
#define AFX_IDC_MAGNIFY 30978 // print preview zoom
#define AFX_IDC_SMALLARROWS 30979 // splitter
#define AFX_IDC_HSPLITBAR 30980 // splitter
#define AFX_IDC_VSPLITBAR 30981 // splitter
#define AFX_IDC_NODROPCRSR 30982 // No Drop Cursor
#define AFX_IDC_TRACKNWSE 30983 // tracker
#define AFX_IDC_TRACKNESW 30984 // tracker
#define AFX_IDC_TRACKNS 30985 // tracker
#define AFX_IDC_TRACKWE 30986 // tracker
#define AFX_IDC_TRACK4WAY 30987 // tracker
#define AFX_IDC_MOVE4WAY 30988 // resize bar (server only)
// Wheel mouse cursors
// NOTE: values must be in this order! See CScrollView::OnTimer()
#define AFX_IDC_MOUSE_PAN_NW 30998 // pan east
#define AFX_IDC_MOUSE_PAN_N 30999 // pan northeast
#define AFX_IDC_MOUSE_PAN_NE 31000 // pan north
#define AFX_IDC_MOUSE_PAN_W 31001 // pan northwest
#define AFX_IDC_MOUSE_PAN_HV 31002 // pan both axis
#define AFX_IDC_MOUSE_PAN_E 31003 // pan west
#define AFX_IDC_MOUSE_PAN_SW 31004 // pan south-west
#define AFX_IDC_MOUSE_PAN_S 31005 // pan south
#define AFX_IDC_MOUSE_PAN_SE 31006 // pan south-east
#define AFX_IDC_MOUSE_PAN_HORZ 31007 // pan X-axis
#define AFX_IDC_MOUSE_PAN_VERT 31008 // pan Y-axis
// Wheel mouse bitmaps
#define AFX_IDC_MOUSE_ORG_HORZ 31009 // anchor for horz only
#define AFX_IDC_MOUSE_ORG_VERT 31010 // anchor for vert only
#define AFX_IDC_MOUSE_ORG_HV 31011 // anchor for horz/vert
#define AFX_IDC_MOUSE_MASK 31012
// Mini frame window bitmap ID
#define AFX_IDB_MINIFRAME_MENU 30994
// CheckListBox checks bitmap ID
#define AFX_IDB_CHECKLISTBOX_95 30996
// AFX standard accelerator resources
#define AFX_IDR_PREVIEW_ACCEL 30997
// AFX standard ICON IDs (for MFC V1 apps) (0x7A01->)
#define AFX_IDI_STD_MDIFRAME 31233
#define AFX_IDI_STD_FRAME 31234
/////////////////////////////////////////////////////////////////////////////
// AFX OLE control implementation - control IDs (AFX_IDC)
// Font property page
#define AFX_IDC_FONTPROP 1000
#define AFX_IDC_FONTNAMES 1001
#define AFX_IDC_FONTSTYLES 1002
#define AFX_IDC_FONTSIZES 1003
#define AFX_IDC_STRIKEOUT 1004
#define AFX_IDC_UNDERLINE 1005
#define AFX_IDC_SAMPLEBOX 1006
// Color property page
#define AFX_IDC_COLOR_BLACK 1100
#define AFX_IDC_COLOR_WHITE 1101
#define AFX_IDC_COLOR_RED 1102
#define AFX_IDC_COLOR_GREEN 1103
#define AFX_IDC_COLOR_BLUE 1104
#define AFX_IDC_COLOR_YELLOW 1105
#define AFX_IDC_COLOR_MAGENTA 1106
#define AFX_IDC_COLOR_CYAN 1107
#define AFX_IDC_COLOR_GRAY 1108
#define AFX_IDC_COLOR_LIGHTGRAY 1109
#define AFX_IDC_COLOR_DARKRED 1110
#define AFX_IDC_COLOR_DARKGREEN 1111
#define AFX_IDC_COLOR_DARKBLUE 1112
#define AFX_IDC_COLOR_LIGHTBROWN 1113
#define AFX_IDC_COLOR_DARKMAGENTA 1114
#define AFX_IDC_COLOR_DARKCYAN 1115
#define AFX_IDC_COLORPROP 1116
#define AFX_IDC_SYSTEMCOLORS 1117
// Picture porperty page
#define AFX_IDC_PROPNAME 1201
#define AFX_IDC_PICTURE 1202
#define AFX_IDC_BROWSE 1203
#define AFX_IDC_CLEAR 1204
/////////////////////////////////////////////////////////////////////////////
// IDRs for OLE control standard components
// Standard propery page dialogs app should leave alone (0x7E01->)
#define AFX_IDD_PROPPAGE_COLOR 32257
#define AFX_IDD_PROPPAGE_FONT 32258
#define AFX_IDD_PROPPAGE_PICTURE 32259
#define AFX_IDB_TRUETYPE 32384
/////////////////////////////////////////////////////////////////////////////
// Standard OLE control strings
// OLE Control page strings
#define AFX_IDS_PROPPAGE_UNKNOWN 0xFE01
#define AFX_IDS_COLOR_DESKTOP 0xFE04
#define AFX_IDS_COLOR_APPWORKSPACE 0xFE05
#define AFX_IDS_COLOR_WNDBACKGND 0xFE06
#define AFX_IDS_COLOR_WNDTEXT 0xFE07
#define AFX_IDS_COLOR_MENUBAR 0xFE08
#define AFX_IDS_COLOR_MENUTEXT 0xFE09
#define AFX_IDS_COLOR_ACTIVEBAR 0xFE0A
#define AFX_IDS_COLOR_INACTIVEBAR 0xFE0B
#define AFX_IDS_COLOR_ACTIVETEXT 0xFE0C
#define AFX_IDS_COLOR_INACTIVETEXT 0xFE0D
#define AFX_IDS_COLOR_ACTIVEBORDER 0xFE0E
#define AFX_IDS_COLOR_INACTIVEBORDER 0xFE0F
#define AFX_IDS_COLOR_WNDFRAME 0xFE10
#define AFX_IDS_COLOR_SCROLLBARS 0xFE11
#define AFX_IDS_COLOR_BTNFACE 0xFE12
#define AFX_IDS_COLOR_BTNSHADOW 0xFE13
#define AFX_IDS_COLOR_BTNTEXT 0xFE14
#define AFX_IDS_COLOR_BTNHIGHLIGHT 0xFE15
#define AFX_IDS_COLOR_DISABLEDTEXT 0xFE16
#define AFX_IDS_COLOR_HIGHLIGHT 0xFE17
#define AFX_IDS_COLOR_HIGHLIGHTTEXT 0xFE18
#define AFX_IDS_REGULAR 0xFE19
#define AFX_IDS_BOLD 0xFE1A
#define AFX_IDS_ITALIC 0xFE1B
#define AFX_IDS_BOLDITALIC 0xFE1C
#define AFX_IDS_SAMPLETEXT 0xFE1D
#define AFX_IDS_DISPLAYSTRING_FONT 0xFE1E
#define AFX_IDS_DISPLAYSTRING_COLOR 0xFE1F
#define AFX_IDS_DISPLAYSTRING_PICTURE 0xFE20
#define AFX_IDS_PICTUREFILTER 0xFE21
#define AFX_IDS_PICTYPE_UNKNOWN 0xFE22
#define AFX_IDS_PICTYPE_NONE 0xFE23
#define AFX_IDS_PICTYPE_BITMAP 0xFE24
#define AFX_IDS_PICTYPE_METAFILE 0xFE25
#define AFX_IDS_PICTYPE_ICON 0xFE26
#define AFX_IDS_COLOR_PPG 0xFE28
#define AFX_IDS_COLOR_PPG_CAPTION 0xFE29
#define AFX_IDS_FONT_PPG 0xFE2A
#define AFX_IDS_FONT_PPG_CAPTION 0xFE2B
#define AFX_IDS_PICTURE_PPG 0xFE2C
#define AFX_IDS_PICTURE_PPG_CAPTION 0xFE2D
#define AFX_IDS_PICTUREBROWSETITLE 0xFE30
#define AFX_IDS_BORDERSTYLE_0 0xFE31
#define AFX_IDS_BORDERSTYLE_1 0xFE32
// OLE Control verb names
#define AFX_IDS_VERB_EDIT 0xFE40
#define AFX_IDS_VERB_PROPERTIES 0xFE41
// OLE Control internal error messages
#define AFX_IDP_PICTURECANTOPEN 0xFE83
#define AFX_IDP_PICTURECANTLOAD 0xFE84
#define AFX_IDP_PICTURETOOLARGE 0xFE85
#define AFX_IDP_PICTUREREADFAILED 0xFE86
// Standard OLE Control error strings
#define AFX_IDP_E_ILLEGALFUNCTIONCALL 0xFEA0
#define AFX_IDP_E_OVERFLOW 0xFEA1
#define AFX_IDP_E_OUTOFMEMORY 0xFEA2
#define AFX_IDP_E_DIVISIONBYZERO 0xFEA3
#define AFX_IDP_E_OUTOFSTRINGSPACE 0xFEA4
#define AFX_IDP_E_OUTOFSTACKSPACE 0xFEA5
#define AFX_IDP_E_BADFILENAMEORNUMBER 0xFEA6
#define AFX_IDP_E_FILENOTFOUND 0xFEA7
#define AFX_IDP_E_BADFILEMODE 0xFEA8
#define AFX_IDP_E_FILEALREADYOPEN 0xFEA9
#define AFX_IDP_E_DEVICEIOERROR 0xFEAA
#define AFX_IDP_E_FILEALREADYEXISTS 0xFEAB
#define AFX_IDP_E_BADRECORDLENGTH 0xFEAC
#define AFX_IDP_E_DISKFULL 0xFEAD
#define AFX_IDP_E_BADRECORDNUMBER 0xFEAE
#define AFX_IDP_E_BADFILENAME 0xFEAF
#define AFX_IDP_E_TOOMANYFILES 0xFEB0
#define AFX_IDP_E_DEVICEUNAVAILABLE 0xFEB1
#define AFX_IDP_E_PERMISSIONDENIED 0xFEB2
#define AFX_IDP_E_DISKNOTREADY 0xFEB3
#define AFX_IDP_E_PATHFILEACCESSERROR 0xFEB4
#define AFX_IDP_E_PATHNOTFOUND 0xFEB5
#define AFX_IDP_E_INVALIDPATTERNSTRING 0xFEB6
#define AFX_IDP_E_INVALIDUSEOFNULL 0xFEB7
#define AFX_IDP_E_INVALIDFILEFORMAT 0xFEB8
#define AFX_IDP_E_INVALIDPROPERTYVALUE 0xFEB9
#define AFX_IDP_E_INVALIDPROPERTYARRAYINDEX 0xFEBA
#define AFX_IDP_E_SETNOTSUPPORTEDATRUNTIME 0xFEBB
#define AFX_IDP_E_SETNOTSUPPORTED 0xFEBC
#define AFX_IDP_E_NEEDPROPERTYARRAYINDEX 0xFEBD
#define AFX_IDP_E_SETNOTPERMITTED 0xFEBE
#define AFX_IDP_E_GETNOTSUPPORTEDATRUNTIME 0xFEBF
#define AFX_IDP_E_GETNOTSUPPORTED 0xFEC0
#define AFX_IDP_E_PROPERTYNOTFOUND 0xFEC1
#define AFX_IDP_E_INVALIDCLIPBOARDFORMAT 0xFEC2
#define AFX_IDP_E_INVALIDPICTURE 0xFEC3
#define AFX_IDP_E_PRINTERERROR 0xFEC4
#define AFX_IDP_E_CANTSAVEFILETOTEMP 0xFEC5
#define AFX_IDP_E_SEARCHTEXTNOTFOUND 0xFEC6
#define AFX_IDP_E_REPLACEMENTSTOOLONG 0xFEC7
/////////////////////////////////////////////////////////////////////////////
#ifdef _AFX_MINREBUILD
#pragma component(minrebuild, on)
#endif
#endif //__AFXRES_H__
/////////////////////////////////////////////////////////////////////////////
+276
View File
@@ -0,0 +1,276 @@
/*
* Copyright (c) 2003 Matteo Frigo
* Copyright (c) 2003 Massachusetts Institute of Technology
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* header file for fftw3 */
/* $Id: fftw3.h,v 1.1 2005/10/28 19:01:21 hartwork Exp $ */
#ifndef FFTW3_H
#define FFTW3_H
#if defined(__ICC) || defined(_MSC_VER)
#pragma comment ( lib, "fftw3" )
#endif
#include <stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/* If <complex.h> is included, use the C99 complex type. Otherwise
define a type bit-compatible with C99 complex */
#ifdef _Complex_I
# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
#else
# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
#endif
#define FFTW_CONCAT(prefix, name) prefix ## name
#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name)
#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name)
#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name)
enum fftw_r2r_kind_do_not_use_me {
FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2,
FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6,
FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10
};
struct fftw_iodim_do_not_use_me {
int n; /* dimension size */
int is; /* input stride */
int os; /* output stride */
};
/*
huge second-order macro that defines prototypes for all API
functions. We expand this macro for each supported precision
X: name-mangling macro
R: real data type
C: complex data type
*/
#define FFTW_DEFINE_API(X, R, C) \
\
FFTW_DEFINE_COMPLEX(R, C); \
\
typedef struct X(plan_s) *X(plan); \
\
typedef struct fftw_iodim_do_not_use_me X(iodim); \
\
typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \
\
void X(execute)(const X(plan) p); \
\
X(plan) X(plan_dft)(int rank, const int *n, \
C *in, C *out, int sign, unsigned flags); \
\
X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \
unsigned flags); \
X(plan) X(plan_dft_2d)(int nx, int ny, \
C *in, C *out, int sign, unsigned flags); \
X(plan) X(plan_dft_3d)(int nx, int ny, int nz, \
C *in, C *out, int sign, unsigned flags); \
\
X(plan) X(plan_many_dft)(int rank, const int *n, \
int howmany, \
C *in, const int *inembed, \
int istride, int idist, \
C *out, const int *onembed, \
int ostride, int odist, \
int sign, unsigned flags); \
\
X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
C *in, C *out, \
int sign, unsigned flags); \
X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
R *ri, R *ii, R *ro, R *io, \
unsigned flags); \
\
void X(execute_dft)(const X(plan) p, C *in, C *out); \
void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, R *ro, R *io); \
\
X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \
int howmany, \
R *in, const int *inembed, \
int istride, int idist, \
C *out, const int *onembed, \
int ostride, int odist, \
unsigned flags); \
\
X(plan) X(plan_dft_r2c)(int rank, const int *n, \
R *in, C *out, unsigned flags); \
\
X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \
X(plan) X(plan_dft_r2c_2d)(int nx, int ny, \
R *in, C *out, unsigned flags); \
X(plan) X(plan_dft_r2c_3d)(int nx, int ny, \
int nz, \
R *in, C *out, unsigned flags); \
\
\
X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \
int howmany, \
C *in, const int *inembed, \
int istride, int idist, \
R *out, const int *onembed, \
int ostride, int odist, \
unsigned flags); \
\
X(plan) X(plan_dft_c2r)(int rank, const int *n, \
C *in, R *out, unsigned flags); \
\
X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \
X(plan) X(plan_dft_c2r_2d)(int nx, int ny, \
C *in, R *out, unsigned flags); \
X(plan) X(plan_dft_c2r_3d)(int nx, int ny, \
int nz, \
C *in, R *out, unsigned flags); \
\
X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
R *in, C *out, \
unsigned flags); \
X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
C *in, R *out, \
unsigned flags); \
\
X(plan) X(plan_guru_split_dft_r2c)(int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
R *in, R *ro, R *io, \
unsigned flags); \
X(plan) X(plan_guru_split_dft_c2r)(int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
R *ri, R *ii, R *out, \
unsigned flags); \
\
void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \
void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \
\
void X(execute_split_dft_r2c)(const X(plan) p, R *in, R *ro, R *io); \
void X(execute_split_dft_c2r)(const X(plan) p, R *ri, R *ii, R *out); \
\
X(plan) X(plan_many_r2r)(int rank, const int *n, \
int howmany, \
R *in, const int *inembed, \
int istride, int idist, \
R *out, const int *onembed, \
int ostride, int odist, \
const X(r2r_kind) *kind, unsigned flags); \
\
X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \
const X(r2r_kind) *kind, unsigned flags); \
\
X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \
X(r2r_kind) kind, unsigned flags); \
X(plan) X(plan_r2r_2d)(int nx, int ny, R *in, R *out, \
X(r2r_kind) kindx, X(r2r_kind) kindy, \
unsigned flags); \
X(plan) X(plan_r2r_3d)(int nx, int ny, int nz, \
R *in, R *out, X(r2r_kind) kindx, \
X(r2r_kind) kindy, X(r2r_kind) kindz, \
unsigned flags); \
\
X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
R *in, R *out, \
const X(r2r_kind) *kind, unsigned flags); \
void X(execute_r2r)(const X(plan) p, R *in, R *out); \
\
void X(destroy_plan)(X(plan) p); \
void X(forget_wisdom)(void); \
void X(cleanup)(void); \
\
void X(plan_with_nthreads)(int nthreads); \
int X(init_threads)(void); \
void X(cleanup_threads)(void); \
\
void X(export_wisdom_to_file)(FILE *output_file); \
char *X(export_wisdom_to_string)(void); \
void X(export_wisdom)(void (*write_char)(char c, void *), void *data); \
int X(import_system_wisdom)(void); \
int X(import_wisdom_from_file)(FILE *input_file); \
int X(import_wisdom_from_string)(const char *input_string); \
int X(import_wisdom)(int (*read_char)(void *), void *data); \
\
void X(fprint_plan)(const X(plan) p, FILE *output_file); \
void X(print_plan)(const X(plan) p); \
\
void *X(malloc)(size_t n); \
void X(free)(void *p); \
\
void X(flops)(const X(plan) p, double *add, double *mul, double *fma); \
\
extern const char X(version)[]; \
extern const char X(cc)[]; \
extern const char X(codelet_optim)[];
/* end of FFTW_DEFINE_API macro */
FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
#define FFTW_FORWARD (-1)
#define FFTW_BACKWARD (+1)
/* documented flags */
#define FFTW_MEASURE (0U)
#define FFTW_DESTROY_INPUT (1U << 0)
#define FFTW_UNALIGNED (1U << 1)
#define FFTW_CONSERVE_MEMORY (1U << 2)
#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */
#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */
#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */
#define FFTW_ESTIMATE (1U << 6)
/* undocumented beyond-guru flags */
#define FFTW_ESTIMATE_PATIENT (1U << 7)
#define FFTW_BELIEVE_PCOST (1U << 8)
#define FFTW_DFT_R2HC_ICKY (1U << 9)
#define FFTW_NONTHREADED_ICKY (1U << 10)
#define FFTW_NO_BUFFERING (1U << 11)
#define FFTW_NO_INDIRECT_OP (1U << 12)
#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */
#define FFTW_NO_RANK_SPLITS (1U << 14)
#define FFTW_NO_VRANK_SPLITS (1U << 15)
#define FFTW_NO_VRECURSE (1U << 16)
#define FFTW_NO_SIMD (1U << 17)
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* FFTW3_H */
@@ -0,0 +1,259 @@
////////////////////////////////////////////////////////////////////////////////
// Plainamp Toolbar Vis Plugin
//
// Copyright © 2006 Sebastian Pipping <[email protected]>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "../Winamp/vis.h"
#include "../Winamp/wa_ipc.h"
#define PLUGIN_NAME "Plainamp Toolbar Vis Plugin"
#define PLUGIN_VERSION "v0.5"
#define PLUGIN_DESC PLUGIN_NAME " " PLUGIN_VERSION
static char * szClassName = "PlainbarClass";
winampVisModule * getModule( int which );
void config( struct winampVisModule * this_mod );
int init( struct winampVisModule * this_mod );
int render_spec( struct winampVisModule * this_mod );
void quit( struct winampVisModule * this_mod );
// Double buffering data
HDC memDC = NULL; // Memory device context
HBITMAP memBM = NULL; // Memory bitmap (for memDC)
HBITMAP oldBM = NULL; // Old bitmap (from memDC)
HWND hRender = NULL;
int width = 0;
int height = 0;
bool bRunning = false;
HPEN pen = NULL;
WNDPROC WndprocTargetBackup = NULL;
LRESULT CALLBACK WndprocTarget( HWND hwnd, UINT message, WPARAM wp, LPARAM lp );
winampVisHeader hdr = {
VIS_HDRVER,
PLUGIN_DESC,
getModule
};
winampVisModule mod_spec =
{
"Default",
NULL, // hwndParent
NULL, // hDllInstance
0, // sRate
0, // nCh
25, // latencyMS
25, // delayMS
2, // spectrumNch
0, // waveformNch
{ 0, }, // spectrumData
{ 0, }, // waveformData
config,
init,
render_spec,
quit
};
#ifdef __cplusplus
extern "C" {
#endif
__declspec( dllexport ) winampVisHeader * winampVisGetHeader()
{
return &hdr;
}
#ifdef __cplusplus
}
#endif
winampVisModule * getModule( int which )
{
return which ? NULL : &mod_spec;
}
void config( struct winampVisModule * this_mod )
{
MessageBox(
this_mod->hwndParent,
PLUGIN_DESC "\n"
"\n"
"Copyright © 2006 Sebastian Pipping \n"
"<[email protected]>\n"
"\n"
"--> http://www.hartwork.org",
"About",
MB_ICONINFORMATION
);
}
LRESULT CALLBACK WndprocTarget( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
switch( message )
{
case WM_SIZE:
width = LOWORD( lp );
height = HIWORD( lp );
break;
case WM_DESTROY:
bRunning = false;
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hwnd, message, wp, lp );
}
int init( struct winampVisModule * this_mod )
{
if( !this_mod ) return 1;
// Register message
const int IPC_GETPLAINBARTARGET = ( int )SendMessage( this_mod->hwndParent, WM_WA_IPC, ( WPARAM )"IPC_GETPLAINBARTARGET", IPC_REGISTER_WINAMP_IPCMESSAGE );
if( IPC_GETPLAINBARTARGET <= 0 ) return 1;
// Get render parent
HWND hRenderParent = ( HWND )SendMessage( this_mod->hwndParent, WM_WA_IPC, 0, IPC_GETPLAINBARTARGET );
if( !IsWindow( hRenderParent ) ) return 1;
// Plug our child in
WNDCLASS wc;
ZeroMemory( &wc, sizeof( WNDCLASS ) );
wc.lpfnWndProc = WndprocTarget;
wc.hInstance = this_mod->hDllInstance;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.lpszClassName = szClassName;
if( !RegisterClass( &wc ) ) return 1;
RECT r;
GetClientRect( hRenderParent, &r );
width = r.right - r.left;
height = r.bottom - r.top;
hRender = CreateWindowEx(
0,
szClassName,
"",
WS_CHILD | WS_VISIBLE,
0,
0,
width,
height,
hRenderParent,
NULL,
this_mod->hDllInstance,
0
);
if( !hRender )
{
UnregisterClass( szClassName, this_mod->hDllInstance );
return 1;
}
// Create doublebuffer
const HDC hdc = GetDC( hRender );
memDC = CreateCompatibleDC( hdc );
memBM = CreateCompatibleBitmap( hdc, 576, 256 );
oldBM = ( HBITMAP )SelectObject( memDC, memBM );
ReleaseDC( hRender, hdc );
pen = CreatePen( PS_SOLID, 0, GetSysColor( COLOR_APPWORKSPACE ) );
bRunning = true;
return 0;
}
int render_spec( struct winampVisModule * this_mod )
{
// Clear background
RECT rect = { 0, 0, 576, 256 };
FillRect(memDC, &rect, ( HBRUSH )( COLOR_3DFACE + 1 ) );
// Draw analyser
SelectObject( memDC, pen );
for( int x = 0; x < 576; x++ )
{
int val = 0;
for( int y = 0; y < this_mod->nCh; y++ )
{
if( this_mod->spectrumData[ y ][ x ] > val )
{
val = this_mod->spectrumData[ y ][ x ];
}
}
MoveToEx( memDC, x, 256, NULL );
LineTo( memDC, x, 256 - val );
}
// Copy doublebuffer to window
HDC hdc = GetDC( hRender );
StretchBlt( hdc, 0, 0, width, height, memDC, 0, 0, 576, 256, SRCCOPY );
ReleaseDC( hRender, hdc );
return bRunning ? 0 : 1;
}
void quit( struct winampVisModule * this_mod )
{
if( bRunning )
{
DestroyWindow( hRender );
}
UnregisterClass( szClassName, this_mod->hDllInstance );
// Delete doublebuffer
SelectObject( memDC, oldBM );
DeleteObject( memDC );
DeleteObject( memBM );
DeleteObject( pen );
}
+332
View File
@@ -0,0 +1,332 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id: zconf.h,v 1.1 2005/10/10 21:08:30 hartwork Exp $ */
#ifndef ZCONF_H
#define ZCONF_H
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
*/
#ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define deflateBound z_deflateBound
# define deflatePrime z_deflatePrime
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateCopy z_inflateCopy
# define inflateReset z_inflateReset
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define zError z_zError
# define alloc_func z_alloc_func
# define free_func z_free_func
# define in_func z_in_func
# define out_func z_out_func
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# define z_off_t off_t
#endif
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if defined(__OS400__)
# define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
# ifdef FAR
# undef FAR
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
# pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND")
# pragma map(deflateBound,"DEBND")
# pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI")
# pragma map(compressBound,"CMBND")
# pragma map(inflate_table,"INTABL")
# pragma map(inflate_fast,"INFA")
# pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */
File diff suppressed because it is too large. Load diff