2011-05-21 18:17:37 +00:00
/*
Copyright ( C ) 2011 Birunthan Mohanathas ( www . poiru . net )
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
# include "StdAfx.h"
# include "PlayerFoobar.h"
2011-06-19 14:58:48 +00:00
CPlayer * CPlayerFoobar : : c_Player = NULL ;
2011-07-15 15:18:02 +00:00
extern HINSTANCE g_Instance ;
2011-05-22 14:45:54 +00:00
2011-05-21 18:17:37 +00:00
/*
* * CPlayerFoobar
* *
* * Constructor .
* *
*/
2011-05-22 08:06:43 +00:00
CPlayerFoobar : : CPlayerFoobar ( ) : CPlayer ( ) ,
2011-05-21 18:17:37 +00:00
m_Window ( ) ,
2011-07-31 08:58:43 +00:00
m_FooWindow ( ) ,
m_MaximizeOnStart ( false )
2011-05-21 18:17:37 +00:00
{
Initialize ( ) ;
}
/*
* * ~ CPlayerFoobar
* *
* * Constructor .
* *
*/
CPlayerFoobar : : ~ CPlayerFoobar ( )
{
2011-06-19 14:58:48 +00:00
c_Player = NULL ;
2011-05-21 18:17:37 +00:00
Uninitialize ( ) ;
}
2011-06-19 14:58:48 +00:00
/*
* * Create
* *
* * Creates a shared class object .
* *
*/
CPlayer * CPlayerFoobar : : Create ( )
{
if ( ! c_Player )
{
c_Player = new CPlayerFoobar ( ) ;
}
return c_Player ;
}
2011-05-21 18:17:37 +00:00
/*
* * Initialize
* *
* * Create receiver window .
* *
*/
void CPlayerFoobar : : Initialize ( )
{
// Create windows class
WNDCLASS wc = { 0 } ;
2011-07-15 15:18:02 +00:00
wc . hInstance = g_Instance ;
2011-05-21 18:17:37 +00:00
wc . lpfnWndProc = WndProc ;
wc . lpszClassName = L " NowPlayingFoobarClass " ;
RegisterClass ( & wc ) ;
2011-06-12 10:05:37 +00:00
// Create window
2011-05-21 18:17:37 +00:00
m_Window = CreateWindow ( L " NowPlayingFoobarClass " ,
L " ReceiverWindow " ,
WS_DISABLED ,
CW_USEDEFAULT ,
CW_USEDEFAULT ,
CW_USEDEFAULT ,
CW_USEDEFAULT ,
NULL ,
NULL ,
2011-07-15 15:18:02 +00:00
g_Instance ,
2011-05-21 18:17:37 +00:00
this ) ;
m_FooWindow = FindWindow ( L " foo_rainmeter_class " , NULL ) ;
if ( m_FooWindow )
{
int version = ( int ) SendMessage ( m_FooWindow , WM_USER , 0 , FOO_GETVERSION ) ;
if ( version < 100 )
{
2011-10-12 13:34:04 +00:00
const WCHAR * error = L " Your copy of the foo_rainmeter.dll plugin for foobar2000 is outdated. \n Download the latest version from foo-rainmeter.googlecode.com and try again. " ;
MessageBox ( NULL , error , L " Rainmeter " , MB_OK | MB_ICONERROR | MB_TOPMOST ) ;
2011-05-21 18:17:37 +00:00
m_FooWindow = NULL ;
}
else
{
2011-06-19 14:58:48 +00:00
m_Initialized = true ;
2011-05-21 18:17:37 +00:00
SendMessage ( m_FooWindow , WM_USER , ( WPARAM ) m_Window , FOO_SETCALLBACK ) ;
}
}
}
/*
* * Uninitialize
* *
* * Destroy reciever window .
* *
*/
void CPlayerFoobar : : Uninitialize ( )
{
if ( m_FooWindow )
{
SendMessage ( m_FooWindow , WM_USER , 0 , FOO_REMOVECALLBACK ) ;
}
DestroyWindow ( m_Window ) ;
2011-07-15 15:18:02 +00:00
UnregisterClass ( L " NowPlayingFoobarClass " , g_Instance ) ;
2011-05-21 18:17:37 +00:00
}
/*
* * WndProc
* *
* * Window procedure for the reciever window .
* *
*/
LRESULT CALLBACK CPlayerFoobar : : WndProc ( HWND hwnd , UINT msg , WPARAM wParam , LPARAM lParam )
{
2011-06-17 19:07:06 +00:00
static CPlayerFoobar * player ;
2011-05-21 18:17:37 +00:00
switch ( msg )
{
case WM_CREATE :
{
// Get pointer to the CPlayerFoobar class from the CreateWindow call
LPVOID params = ( ( CREATESTRUCT * ) lParam ) - > lpCreateParams ;
2011-06-17 19:07:06 +00:00
player = ( CPlayerFoobar * ) params ;
2011-05-21 18:17:37 +00:00
return 0 ;
}
case WM_USER :
switch ( lParam )
{
case FOO_GETVERSION :
return 100 ;
case FOO_STATECHANGE :
{
2011-06-17 19:07:06 +00:00
PLAYSTATE ps = ( PLAYSTATE ) wParam ;
2011-05-21 18:17:37 +00:00
if ( ps = = PLAYER_STOPPED )
{
2011-06-17 19:07:06 +00:00
player - > ClearData ( ) ;
2011-05-21 18:17:37 +00:00
}
else
{
2011-06-17 19:07:06 +00:00
player - > m_State = ps ;
2011-05-21 18:17:37 +00:00
}
}
break ;
case FOO_TIMECHANGE :
2011-06-17 19:07:06 +00:00
player - > m_Position = ( UINT ) wParam ;
2011-05-21 18:17:37 +00:00
break ;
case FOO_VOLUMECHANGE :
2011-06-17 19:07:06 +00:00
player - > m_Volume = ( UINT ) wParam ;
2011-05-21 18:17:37 +00:00
break ;
case FOO_PLAYERSTART :
2011-07-01 20:34:12 +00:00
player - > m_Initialized = true ;
2011-06-17 19:07:06 +00:00
player - > m_FooWindow = ( HWND ) wParam ;
2011-07-31 08:58:43 +00:00
if ( player - > m_MaximizeOnStart )
{
SendMessage ( player - > m_FooWindow , WM_USER , 0 , FOO_SHOWPLAYER ) ;
player - > m_MaximizeOnStart = false ;
}
2011-05-21 18:17:37 +00:00
break ;
case FOO_PLAYERQUIT :
2011-06-19 14:58:48 +00:00
player - > m_Initialized = false ;
2011-06-17 19:07:06 +00:00
player - > ClearData ( ) ;
2011-05-21 18:17:37 +00:00
break ;
}
return 0 ;
case WM_COPYDATA :
{
PCOPYDATASTRUCT cds = ( PCOPYDATASTRUCT ) lParam ;
if ( cds - > dwData = = FOO_TRACKCHANGE )
{
2011-06-17 19:07:06 +00:00
if ( player - > m_State ! = PLAYER_PLAYING )
2011-05-21 18:17:37 +00:00
{
2011-06-17 19:07:06 +00:00
player - > m_State = PLAYER_PLAYING ;
2011-05-21 18:17:37 +00:00
}
// In the format "TITLE ARTIST ALBUM LENGTH RATING" (seperated by \t)
WCHAR buffer [ 1024 ] ;
MultiByteToWideChar ( CP_UTF8 , 0 , ( char * ) cds - > lpData , cds - > cbData , buffer , 1024 ) ;
2011-06-17 19:07:06 +00:00
player - > m_Artist = buffer ;
2011-05-21 18:17:37 +00:00
WCHAR * token = wcstok ( buffer , L " \t " ) ;
if ( token )
{
2011-07-24 16:40:20 +00:00
if ( wcscmp ( token , L " " ) = = 0 )
{
player - > m_Title . clear ( ) ;
}
else
{
player - > m_Title = token ;
}
2011-05-21 18:17:37 +00:00
}
token = wcstok ( NULL , L " \t " ) ;
if ( token )
{
2011-07-24 16:40:20 +00:00
if ( wcscmp ( token , L " " ) = = 0 )
{
player - > m_Artist . clear ( ) ;
}
else
{
player - > m_Artist = token ;
}
2011-05-21 18:17:37 +00:00
}
token = wcstok ( NULL , L " \t " ) ;
if ( token )
{
2011-07-24 16:40:20 +00:00
if ( wcscmp ( token , L " " ) = = 0 )
{
player - > m_Album . clear ( ) ;
}
else
{
player - > m_Album = token ;
}
2011-05-21 18:17:37 +00:00
}
token = wcstok ( NULL , L " \t " ) ;
if ( token )
{
2011-06-17 19:07:06 +00:00
player - > m_Duration = _wtoi ( token ) ;
2011-05-21 18:17:37 +00:00
}
token = wcstok ( NULL , L " \t " ) ;
if ( token )
{
2011-06-17 19:07:06 +00:00
player - > m_Rating = _wtoi ( token ) ;
2011-05-21 18:17:37 +00:00
}
token = wcstok ( NULL , L " \t " ) ;
2011-06-17 19:07:06 +00:00
if ( token & & wcscmp ( token , player - > m_FilePath . c_str ( ) ) ! = 0 )
2011-05-21 18:17:37 +00:00
{
2011-06-17 19:07:06 +00:00
// If different file
+ + player - > m_TrackCount ;
player - > m_FilePath = token ;
player - > m_Position = 0 ;
2011-09-08 12:42:03 +00:00
if ( player - > m_Measures & MEASURE_COVER | | player - > m_InstanceCount = = 0 )
2011-05-22 08:06:43 +00:00
{
2011-06-19 14:58:48 +00:00
player - > FindCover ( ) ;
}
2011-09-08 12:42:03 +00:00
if ( player - > m_Measures & MEASURE_LYRICS )
2011-06-19 14:58:48 +00:00
{
player - > FindLyrics ( ) ;
2011-05-22 08:06:43 +00:00
}
2011-05-21 18:17:37 +00:00
}
2011-09-11 10:34:06 +00:00
token = wcstok ( NULL , L " \t " ) ;
if ( token )
{
switch ( _wtoi ( token ) )
{
case 0 :
player - > m_Shuffle = player - > m_Repeat = false ;
break ;
case 1 :
player - > m_Shuffle = true ;
player - > m_Repeat = false ;
break ;
case 2 :
player - > m_Shuffle = false ;
player - > m_Repeat = true ;
break ;
}
}
2011-05-21 18:17:37 +00:00
}
}
return 0 ;
default :
return DefWindowProc ( hwnd , msg , wParam , lParam ) ;
}
}
/*
* * UpdateData
* *
* * Called during each update of the main measure .
* *
*/
void CPlayerFoobar : : UpdateData ( )
{
}
2011-06-09 09:47:55 +00:00
/*
* * Pause
* *
* * Handles the Pause bang .
* *
*/
void CPlayerFoobar : : Pause ( )
{
2011-06-17 19:07:06 +00:00
SendMessage ( m_FooWindow , WM_USER , 0 , FOO_PAUSE ) ;
2011-06-09 09:47:55 +00:00
}
2011-05-21 18:17:37 +00:00
/*
2011-05-24 18:20:35 +00:00
* * Play
2011-05-21 18:17:37 +00:00
* *
2011-05-24 18:20:35 +00:00
* * Handles the Play bang .
2011-05-21 18:17:37 +00:00
* *
*/
void CPlayerFoobar : : Play ( )
{
2011-06-25 12:44:33 +00:00
SendMessage ( m_FooWindow , WM_USER , 0 , ( m_State = = PLAYER_PAUSED ) ? FOO_PLAYPAUSE : FOO_PLAY ) ;
2011-05-21 18:17:37 +00:00
}
/*
* * Stop
* *
* * Handles the Stop bang .
* *
*/
void CPlayerFoobar : : Stop ( )
{
2011-06-17 19:07:06 +00:00
SendMessage ( m_FooWindow , WM_USER , 0 , FOO_STOP ) ;
2011-05-21 18:17:37 +00:00
}
/*
* * Next
* *
* * Handles the Next bang .
* *
*/
void CPlayerFoobar : : Next ( )
{
2011-06-17 19:07:06 +00:00
SendMessage ( m_FooWindow , WM_USER , 0 , FOO_NEXT ) ;
2011-05-21 18:17:37 +00:00
}
/*
* * Previous
* *
* * Handles the Previous bang .
* *
*/
void CPlayerFoobar : : Previous ( )
{
2011-06-17 19:07:06 +00:00
SendMessage ( m_FooWindow , WM_USER , 0 , FOO_PREVIOUS ) ;
2011-05-21 18:17:37 +00:00
}
/*
2011-06-09 09:47:55 +00:00
* * SetPosition
2011-05-21 18:17:37 +00:00
* *
2011-06-09 09:47:55 +00:00
* * Handles the SetPosition bang .
2011-05-21 18:17:37 +00:00
* *
*/
2011-06-09 09:47:55 +00:00
void CPlayerFoobar : : SetPosition ( int position )
2011-05-21 18:17:37 +00:00
{
2011-06-17 19:07:06 +00:00
SendMessage ( m_FooWindow , WM_USER , position , FOO_SETPOSITION ) ;
2011-05-21 18:17:37 +00:00
}
2011-09-11 10:34:06 +00:00
/*
* * SetShuffle
* *
* * Handles the SetShuffle bang .
* *
*/
void CPlayerFoobar : : SetShuffle ( bool state )
{
m_Shuffle = state ;
m_Repeat = state ? ! m_Shuffle : m_Shuffle ;
SendMessage ( m_FooWindow , WM_USER , state ? 1 : 0 , FOO_SETORDER ) ;
}
/*
* * SetRepeat
* *
* * Handles the SetRepeat bang .
* *
*/
void CPlayerFoobar : : SetRepeat ( bool state )
{
m_Repeat = state ;
m_Shuffle = state ? ! m_Repeat : m_Repeat ;
SendMessage ( m_FooWindow , WM_USER , state ? 2 : 0 , FOO_SETORDER ) ;
}
2011-05-21 18:17:37 +00:00
/*
* * SetVolume
* *
* * Handles the SetVolume bang .
* *
*/
void CPlayerFoobar : : SetVolume ( int volume )
{
2011-06-17 19:07:06 +00:00
SendMessage ( m_FooWindow , WM_USER , volume , FOO_SETVOLUME ) ;
2011-05-21 18:17:37 +00:00
}
/*
* * ClosePlayer
* *
* * Handles the ClosePlayer bang .
* *
*/
void CPlayerFoobar : : ClosePlayer ( )
{
2011-06-17 19:07:06 +00:00
SendMessage ( m_FooWindow , WM_USER , 0 , FOO_QUITPLAYER ) ;
2011-05-21 18:17:37 +00:00
}
/*
* * OpenPlayer
* *
* * Handles the OpenPlayer bang .
* *
*/
2011-06-17 19:07:06 +00:00
void CPlayerFoobar : : OpenPlayer ( std : : wstring & path )
2011-05-21 18:17:37 +00:00
{
2011-06-19 14:58:48 +00:00
if ( ! m_Initialized )
2011-05-21 18:17:37 +00:00
{
2011-06-17 19:07:06 +00:00
if ( path . empty ( ) )
2011-05-21 18:17:37 +00:00
{
// Gotta figure out where foobar2000 is located at
HKEY hKey ;
RegOpenKeyEx ( HKEY_CLASSES_ROOT ,
L " Applications \\ foobar2000.exe \\ shell \\ open \\ command " ,
0 ,
KEY_QUERY_VALUE ,
& hKey ) ;
DWORD size = 512 ;
WCHAR * data = new WCHAR [ size ] ;
DWORD type = 0 ;
if ( RegQueryValueEx ( hKey ,
NULL ,
NULL ,
( LPDWORD ) & type ,
( LPBYTE ) data ,
( LPDWORD ) & size ) = = ERROR_SUCCESS )
{
if ( type = = REG_SZ & & data [ 0 ] = = L ' \" ' )
{
2011-06-17 19:07:06 +00:00
path = data ;
2011-05-21 18:17:37 +00:00
path . erase ( 0 , 1 ) ; // Get rid of the leading quote
std : : wstring : : size_type pos = path . find_first_of ( L ' \" ' ) ;
if ( pos ! = std : : wstring : : npos )
{
path . resize ( pos ) ; // Get rid the last quote and everything after it
ShellExecute ( NULL , L " open " , path . c_str ( ) , NULL , NULL , SW_SHOW ) ;
2011-06-17 19:07:06 +00:00
path = path ;
}
else
{
path . clear ( ) ;
2011-05-21 18:17:37 +00:00
}
}
}
delete [ ] data ;
RegCloseKey ( hKey ) ;
}
else
{
2011-06-17 19:07:06 +00:00
ShellExecute ( NULL , L " open " , path . c_str ( ) , NULL , NULL , SW_SHOW ) ;
2011-07-31 08:58:43 +00:00
m_MaximizeOnStart = true ;
2011-05-21 18:17:37 +00:00
}
}
else
{
SendMessage ( m_FooWindow , WM_USER , 0 , FOO_SHOWPLAYER ) ;
}
}