You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kvirc/src/modules/mediaplayer/mp_winampinterface.cpp

567 lines
15 KiB

//=============================================================================
//
// File : mp_winampinterface.cpp
// Created on Mon 28 Mar 2005 23:41:50 by Szymon Stefanek
//
// This file is part of the KVIrc IRC client distribution
// Copyright (C) 2005 Szymon Stefanek <pragma at kvirc dot 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 opinion) 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. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================
#include "mp_winampinterface.h"
#include "kvi_options.h"
#ifdef COMPILE_ON_WINDOWS
#include <tqtextcodec.h>
#include "kvi_locale.h"
#include "kvi_module.h"
#include <windows.h>
#define IPC_STARTPLAY 102
#define IPC_ISPLAYING 104
#define IPC_GETOUTPUTTIME 105
// ** int res = SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETOUTPUTTIME);
// **
// ** IPC_GETOUTPUTTIME returns the position in milliseconds of the
// ** current song (mode = 0), or the song length, in seconds (mode = 1).
// ** Returns -1 if not playing or error.
#define IPC_JUMPTOTIME 106
// ** SendMessage(hwnd_winamp,WM_WA_IPC,ms,IPC_JUMPTOTIME);
// ** IPC_JUMPTOTIME sets the position in milliseconds of the
// ** current song (approximately).
#define IPC_SETPLAYLISTPOS 121
// ** SendMessage(hwnd_winamp,WM_WA_IPC,position,IPC_SETPLAYLISTPOS)
// ** IPC_SETPLAYLISTPOS sets the playlsit position to 'position'.
#define IPC_SETVOLUME 122
// ** SendMessage(hwnd_winamp,WM_WA_IPC,volume,IPC_SETVOLUME);
// ** IPC_SETVOLUME sets the volume of Winamp (from 0-255).
#define IPC_GETLISTLENGTH 124
// ** int length = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTLENGTH);
// ** IPC_GETLISTLENGTH returns the length of the current playlist, in
// ** tracks.
#define IPC_GETETQDATA 127
// ** int data=SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETETQDATA);
// ** IPC_GETETQDATA queries the status of the EQ.
// ** The value returned depends on what 'pos' is set to:
// ** Value Meaning
// ** ------------------
// ** 0-9 The 10 bands of EQ data. 0-63 (+20db - -20db)
// ** 10 The preamp value. 0-63 (+20db - -20db)
// ** 11 Enabled. zero if disabled, nonzero if enabled.
// ** 12 Autoload. zero if disabled, nonzero if enabled.
#define IPC_SETETQDATA 128
// ** SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETETQDATA);
// ** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SETETQDATA);
// ** IPC_SETETQDATA sets the value of the last position retrieved
// ** by IPC_GETETQDATA. This is pretty lame, and we should provide
// ** an extended version that lets you do a MAKELPARAM(pos,value).
// ** someday...
#define IPC_GETPLAYLISTFILE 211
// ** (requires Winamp 2.04+, only usable from plug-ins (not external apps))
// ** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE);
// ** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index].
// ** returns a pointer to it. returns NULL on error.
#define IPC_GETPLAYLISTTITLE 212
// * (requires Winamp 2.04+, only usable from plug-ins (not external apps))
// ** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTTITLE);
// ** IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index].
// ** returns a pointer to it. returns NULL on error.
#define IPC_GET_SHUFFLE 250
// ** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_SHUFFLE);
// **
// ** IPC_GET_SHUFFLE returns the status of the Shuffle option (1 if set)
#define IPC_GET_REPEAT 251
// ** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_REPEAT);
// **
// ** IPC_GET_REPEAT returns the status of the Repeat option (1 if set)
#define IPC_SET_SHUFFLE 252
// ** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_SHUFFLE);
// **
// ** IPC_SET_SHUFFLE sets the status of the Shuffle option (1 to turn it on)
#define IPC_SET_REPEAT 253
// ** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_REPEAT);
// **
// ** IPC_SET_REPEAT sets the status of the Repeat option (1 to turn it on)
#define IPC_GETLISTPOS 125
// ** int pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS);
// ** IPC_GETLISTPOS returns the playlist position. A lot like IPC_WRITEPLAYLIST
// ** only faster since it doesn't have to write out the list. Heh, silly me.
#define IPC_GETINFO 126
// ** int inf=SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETINFO);
// ** IPC_GETINFO returns info about the current playing song. The value
// ** it returns depends on the value of 'mode'.
// ** Mode Meaning
// ** ------------------
// ** 0 Samplerate (i.e. 44100)
// ** 1 Bitrate (i.e. 128)
// ** 2 Channels (i.e. 2)
#define IPC_PLAYFILE 100
// ** COPYDATASTRUCT cds;
// ** cds.dwData = IPC_PLAYFILE;
// ** cds.lpData = (void *) "file.mp3";
// ** cds.cbData = strlen((char *) cds.lpData)+1; // include space for null char
// ** SendMessage(hwnd_winamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds);
// **
// ** This will play the file "file.mp3".
#define IPC_ISPLAYING 104
// ** int res = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING);
// ** IPC_ISPLAYING returns the status of playback.
// ** If it returns 1, it is playing. if it returns 3, it is paused,
// ** if it returns 0, it is not playing.
// The following stuff needs PostMessage(hwnd_winamp,WM_COMMAND,id,0);
#define WINAMP_BUTTON1 40044
#define WINAMP_BUTTON2 40045
#define WINAMP_BUTTON3 40046
#define WINAMP_BUTTON4 40047
#define WINAMP_BUTTON5 40048
#define WINAMP_CMD_PREV WINAMP_BUTTON1
#define WINAMP_CMD_PLAY WINAMP_BUTTON2
#define WINAMP_CMD_PAUSE WINAMP_BUTTON3
#define WINAMP_CMD_STOP WINAMP_BUTTON4
#define WINAMP_CMD_NEXT WINAMP_BUTTON5
#define WINAMP_CMD_TQUIT 40001
#define KVIRC_WM_USER 63112
#define KVIRC_WM_USER_CHECK 13123
#define KVIRC_WM_USER_CHECK_REPLY 13124
#define KVIRC_WM_USER_GETTITLE 5000
#define KVIRC_WM_USER_GETFILE 10000
#define KVIRC_WM_USER_TRANSFER 15000
static TQTextCodec * mediaplayer_get_codec()
{
TQTextCodec * c= TQTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding));
if(!c)c = TQTextCodec::codecForLocale();
return c;
}
static HWND find_winamp(KviWinampInterface * i)
{
HWND hWnd = FindWindow("Winamp v1.x",NULL);
if(!hWnd)
{
// try to start the process ?
i->setLastError(__tr2qs_ctx("Can't find a running winamp window","mediaplayer"));
}
return hWnd;
}
MP_IMPLEMENT_DESCRIPTOR(
KviWinampInterface,
"winamp",
__tr2qs_ctx(
"An interface to the popupar Winamp media player.\n" \
"You can download it from http://www.winamp.com.\n" \
"To use all the features of this interface you must " \
"copy the gen_kvirc.dll plugin found in the KVIrc " \
"distribution directory to the Winamp plugins folder " \
"and restart winamp."
,
"mediaplayer"
)
)
KviWinampInterface::KviWinampInterface()
: KviMediaPlayerInterface()
{
}
KviWinampInterface::~KviWinampInterface()
{
}
int KviWinampInterface::detect(bool bStart)
{
if(find_winamp(this))return 80;
// FIXME : check for Programs Folder\Winamp\Winamp.exe ?
// FIXME : if bStart try to start winamp.exe ?
return 50;
}
#define MP_WINAMP_SENDMESSAGE(__cmdname,__wmmsg,__lparam,__wparam) \
bool KviWinampInterface::__cmdname() \
{ \
HWND hWinamp = find_winamp(this); \
if(hWinamp)SendMessage(hWinamp,__wmmsg,__lparam,__wparam); \
return hWinamp != 0; \
}
#define MP_WINAMP_WM_USER(__cmdname,_ipcmsg) MP_WINAMP_SENDMESSAGE(__cmdname,WM_USER,0,_ipcmsg)
#define MP_WINAMP_WM_COMMAND(__cmdname,_cmdmsg) MP_WINAMP_SENDMESSAGE(__cmdname,WM_COMMAND,_cmdmsg,0)
MP_WINAMP_WM_USER(play,IPC_STARTPLAY)
MP_WINAMP_WM_COMMAND(stop,WINAMP_CMD_STOP)
MP_WINAMP_WM_COMMAND(next,WINAMP_CMD_NEXT)
MP_WINAMP_WM_COMMAND(prev,WINAMP_CMD_PREV)
MP_WINAMP_WM_COMMAND(pause,WINAMP_CMD_PAUSE)
MP_WINAMP_WM_COMMAND(quit,WINAMP_CMD_TQUIT)
int KviWinampInterface::length()
{
int leninsecs = -1;
HWND hWinamp = find_winamp(this);
if(hWinamp)leninsecs = SendMessage(hWinamp,WM_USER,1,IPC_GETOUTPUTTIME);
return leninsecs * 1000;
}
int KviWinampInterface::position()
{
int leninmsecs = -1;
HWND hWinamp = find_winamp(this);
if(hWinamp)leninmsecs = SendMessage(hWinamp,WM_USER,0,IPC_GETOUTPUTTIME);
return leninmsecs;
}
int KviWinampInterface::bitRate()
{
int ret = -1;
HWND hWinamp = find_winamp(this);
if(hWinamp)ret = SendMessage(hWinamp,WM_USER,1,IPC_GETINFO);
return ret;
}
int KviWinampInterface::sampleRate()
{
int ret = -1;
HWND hWinamp = find_winamp(this);
if(hWinamp)ret = SendMessage(hWinamp,WM_USER,0,IPC_GETINFO);
return ret;
}
int KviWinampInterface::channels()
{
int ret = -1;
HWND hWinamp = find_winamp(this);
if(hWinamp)ret = SendMessage(hWinamp,WM_USER,2,IPC_GETINFO);
return ret;
}
KviMediaPlayerInterface::PlayerStatus KviWinampInterface::status()
{
HWND hWinamp = find_winamp(this);
int ret = 1000;
if(hWinamp)ret = SendMessage(hWinamp,WM_USER,0,IPC_ISPLAYING);
switch(ret)
{
case 0:
return KviMediaPlayerInterface::Stopped;
break;
case 3:
return KviMediaPlayerInterface::Paused;
break;
case 1:
return KviMediaPlayerInterface::Playing;
break;
default:
return KviMediaPlayerInterface::Unknown;
break;
}
return KviMediaPlayerInterface::Unknown;
}
TQString KviWinampInterface::mrl()
{
TQString ret;
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
int ret2 = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_CHECK);
if(ret2 =! KVIRC_WM_USER_CHECK_REPLY)
{
setLastError(__tr2qs_ctx("The winamp plugin has not been installed properly. Check /help mediaplayer.nowplaying","mediaplayer"));
return ret;
}
int len = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_GETFILE);
if(len < 4096)
{
char szBuffer[4096];
for(int i = 0;i < len;i++)
{
szBuffer[i] = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_TRANSFER + i);
}
szBuffer[len] = '\0';
TQTextCodec *c=mediaplayer_get_codec();
if (c) ret = c->toUnicode(szBuffer);
else ret=szBuffer;
if(!ret.startsWith("http://",false))
ret.prepend("file://");
}
}
return ret;
}
TQString KviWinampInterface::nowPlaying()
{
TQString ret;
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
int retpippo = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_CHECK);
if(retpippo =! KVIRC_WM_USER_CHECK_REPLY)
{
setLastError(__tr2qs_ctx("The winamp plugin has not been installed properly. Check /help mediaplayer.nowplaying","mediaplayer") );
return ret;
}
int len = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_GETTITLE);
if(len < 4096)
{
char szBuffer[4096];
for(int i = 0;i < len;i++)
{
szBuffer[i] = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_TRANSFER + i);
}
szBuffer[ len ] = '\0';
TQTextCodec *c=mediaplayer_get_codec();
if (c) ret = c->toUnicode(szBuffer);
else ret=szBuffer;
}
}
return ret;
}
bool KviWinampInterface::playMrl(const TQString &mrl)
{
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
TQTextCodec *c=mediaplayer_get_codec();
KviStr szMrl = c ? c->fromUnicode(mrl) : mrl.utf8();
COPYDATASTRUCT cds;
cds.dwData = IPC_PLAYFILE;
cds.lpData = (void *)szMrl.ptr();
cds.cbData = szMrl.len() + 1; // include space for null char
SendMessage(hWinamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM) &cds);
return true;
}
return false;
}
bool KviWinampInterface::setVol(kvs_int_t &iVol)
{
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
SendMessage(hWinamp,WM_USER,iVol,IPC_SETVOLUME);
return true;
}
return false;
}
int KviWinampInterface::getVol()
{
int ret = -1;
HWND hWinamp = find_winamp(this);
if(hWinamp)ret = SendMessage(hWinamp,WM_USER,-666,IPC_SETVOLUME);
return ret;
}
bool KviWinampInterface::jumpTo(kvs_int_t &iPos)
{
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
SendMessage(hWinamp,WM_USER,iPos,IPC_JUMPTOTIME);
return true;
}
return false;
}
bool KviWinampInterface::hide()
{
HWND hWinamp = find_winamp(this);
HWND hWinampPE = FindWindow("Winamp PE",NULL); /*Playlist*/
HWND hWinampEQ = FindWindow("Winamp EQ",NULL); /*Equalizer*/
HWND hWinampMB = FindWindow("Winamp MB",NULL); /*MiniBrowser*/
HWND hWinampGen = FindWindow("Winamp Gen",NULL); /*Library*/
HWND hWinampVideo = FindWindow("Winamp Video",NULL); /*Video*/
if(hWinamp)
{
ShowWindow(hWinamp, SW_HIDE);
if(hWinampPE || hWinampEQ || hWinampMB || hWinampGen || hWinampVideo )
{
if(hWinampPE)
ShowWindow(hWinampPE, SW_HIDE);
if(hWinampEQ)
ShowWindow(hWinampEQ, SW_HIDE);
if(hWinampMB)
ShowWindow(hWinampMB, SW_HIDE);
if(hWinampGen)
ShowWindow(hWinampGen, SW_HIDE);
if(hWinampVideo)
ShowWindow(hWinampVideo, SW_HIDE);
return true;
}
return true;
}
return false;
}
bool KviWinampInterface::show()
{
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
ShowWindow(hWinamp, SW_SHOW);
return true;
}
return false;
}
bool KviWinampInterface::minimize()
{
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
ShowWindow(hWinamp, SW_SHOWMINIMIZED);
return true;
}
return false;
}
bool KviWinampInterface::setPlayListPos(int &iPos)
{
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
SendMessage(hWinamp,WM_USER,iPos,IPC_SETPLAYLISTPOS);
return true;
}
return false;
}
int KviWinampInterface::getPlayListPos()
{
int ret = -1;
HWND hWinamp = find_winamp(this);
if(hWinamp)ret = SendMessage(hWinamp,WM_USER,2,IPC_GETLISTPOS);
return ret;
}
int KviWinampInterface::getListLength()
{
int ret = -1;
HWND hWinamp = find_winamp(this);
if(hWinamp)ret = SendMessage(hWinamp,WM_USER,2,IPC_GETLISTLENGTH);
return ret;
}
bool KviWinampInterface::setEqData(int &iPos, int &iVal)
{
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
SendMessage(hWinamp,WM_USER,iPos,IPC_GETETQDATA);
SendMessage(hWinamp,WM_USER,iVal,IPC_SETETQDATA);
return true;
}
return false;
}
int KviWinampInterface::getEqData(int &ival)
{
HWND hWinamp = find_winamp(this);
int ret = -1;
if(hWinamp)
{
ret = SendMessage(hWinamp,WM_USER,ival,IPC_GETETQDATA);
return ret;
}
return ret;
}
bool KviWinampInterface::getRepeat()
{
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
bool bRepeat = SendMessage(hWinamp,WM_USER,0,IPC_GET_REPEAT);
return bRepeat;
}
return false;
}
bool KviWinampInterface::getShuffle()
{
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
bool bShuffle = SendMessage(hWinamp,WM_USER,0,IPC_GET_SHUFFLE);
return bShuffle;
}
return false;
}
bool KviWinampInterface::setShuffle(bool &bVal)
{
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
bool bRepeat = SendMessage(hWinamp,WM_USER,bVal,IPC_SET_SHUFFLE);
return bRepeat;
}
return false;
}
bool KviWinampInterface::setRepeat(bool &bVal)
{
HWND hWinamp = find_winamp(this);
if(hWinamp)
{
bool bShuffle = SendMessage(hWinamp,WM_USER,bVal,IPC_SET_REPEAT);
return bShuffle;
}
return false;
}
#endif //COMPILE_ON_WINDOWS