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_amipinterface.cpp

401 lines
7.8 KiB

#include "mp_amipinterface.h"
#include "kvi_options.h"
#ifdef COMPILE_ON_WINDOWS
#include <tqtextcodec.h>
#include "kvi_locale.h"
#include "kvi_module.h"
#include <windows.h>
enum ac_StartMode
{
AC_START_ALL = 0,
AC_START_CLIENT,
AC_START_SERVER,
AC_START_NONE
};
enum ac_ErrorCode
{
AC_ERR_NOERROR = 0,
AC_ERR_CLIENTISNULL,
AC_ERR_EXCEPTION,
AC_ERR_CONNECTIONFAILED,
AC_ERR_SERVERNOTRUNNING
};
#define AC_BUFFER_SIZE 2048
static HINSTANCE amip_dll = NULL;
#define MP_AC_DYNPTR(__rettype,__func,__args) \
typedef __rettype (CALLBACK* lp_##__func)(__args); \
lp_##__func __func
#define MP_AC_FUNC(__func) \
__func = (lp_##__func)GetProcAddress(amip_dll,#__func); \
if(!__func) { \
FreeLibrary(amip_dll); \
return false; \
}
#define COMMA() ,
MP_AC_DYNPTR(void, ac_init, int mode);
MP_AC_DYNPTR(void, ac_uninit, void);
MP_AC_DYNPTR(void, ac_getDestHost, char *out);
MP_AC_DYNPTR(int, ac_getDestPort, void);
MP_AC_DYNPTR(bool, ac_pingServer, const char *host COMMA() int port COMMA() int timeout);
MP_AC_DYNPTR(int, ac_exec, const char *cmd);
MP_AC_DYNPTR(int, ac_eval, const char *cmd COMMA() char *result);
static bool loadAmipDll()
{
amip_dll = LoadLibrary("ac.dll");
if (!amip_dll) return false;
MP_AC_FUNC(ac_init);
MP_AC_FUNC(ac_uninit);
MP_AC_FUNC(ac_getDestHost);
MP_AC_FUNC(ac_getDestPort);
MP_AC_FUNC(ac_pingServer);
MP_AC_FUNC(ac_eval);
MP_AC_FUNC(ac_exec);
return true;
};
static TQTextCodec * mediaplayer_get_codec()
{
TQTextCodec * c= TQTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding));
if(!c)c = TQTextCodec::codecForLocale();
return c;
}
MP_IMPLEMENT_DESCRIPTOR(
KviAmipInterface,
"amip",
__tr2qs_ctx(
"An interface to the AMIP plug-in.\n" \
"You can download it from http://amip.tools-for.net.\n" \
"To use this interface you must " \
"install AMIP plug-in for your player."
,
"mediaplayer"
)
)
KviAmipInterface::KviAmipInterface()
: KviMediaPlayerInterface()
{
if(!amip_dll) {
bool res = loadAmipDll();
if(!res) {
amip_dll = NULL;
return;
}
ac_init(AC_START_CLIENT);
}
}
KviAmipInterface::~KviAmipInterface()
{
if(!amip_dll) return;
ac_uninit();
FreeLibrary(amip_dll);
amip_dll = NULL;
}
int KviAmipInterface::detect(bool bStart)
{
if(!amip_dll) return 0;
char host[AC_BUFFER_SIZE];
ac_getDestHost(host);
if(ac_pingServer(host, ac_getDestPort(), 5000)) return 99;
return 1;
}
#define MP_AMIP_COMMAND(__cmdname,__acmd) \
bool KviAmipInterface::__cmdname() \
{ \
return (ac_exec(__acmd) == AC_ERR_NOERROR); \
}
MP_AMIP_COMMAND(play,"control play")
MP_AMIP_COMMAND(stop,"control stop")
MP_AMIP_COMMAND(next,"control >")
MP_AMIP_COMMAND(prev,"control <")
MP_AMIP_COMMAND(pause,"control pause")
MP_AMIP_COMMAND(quit,"control exit")
// helper function for evaluating variables returning integers
int eval_int(const char *var)
{
if(!amip_dll) return -1;
char buff[AC_BUFFER_SIZE];
int res = -1;
if (AC_ERR_NOERROR == ac_eval(var, buff)) {
res = atoi(buff);
}
return res;
}
TQString eval_str(const char *var)
{
TQString res;
if(!amip_dll) return res;
char buff[AC_BUFFER_SIZE];
if (AC_ERR_NOERROR == ac_eval(var, buff)) {
res.append(buff);
}
return res;
}
int KviAmipInterface::length()
{
return eval_int("var_sl") * 1000;
}
int KviAmipInterface::position()
{
return eval_int("var_psec") * 1000;
}
int KviAmipInterface::bitRate()
{
return eval_int("var_br");
}
int KviAmipInterface::sampleRate()
{
return eval_int("var_sr");
}
int KviAmipInterface::channels()
{
int ret = -1;
if(eval_str("var_typ").startsWith("Stereo")) {
ret = 2;
} else if(eval_str("var_typ").startsWith("Mono")) {
ret = 1;
}
return ret;
}
KviMediaPlayerInterface::PlayerStatus KviAmipInterface::status()
{
int ret = eval_int("var_stat");
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 KviAmipInterface::mrl()
{
TQString ret;
TQString fn = eval_str("var_fn");
TQTextCodec *c=mediaplayer_get_codec();
if (c) ret = c->toUnicode(fn);
else ret=fn;
if(!ret.startsWith("http://",false))
ret.prepend("file://");
return ret;
}
TQString getAmipString(const char * var) {
TQString ret;
TQString s = eval_str(var);
TQTextCodec *c=mediaplayer_get_codec();
if (c) ret = c->toUnicode(s);
else ret=s;
return ret;
}
TQString KviAmipInterface::nowPlaying()
{
return getAmipString("var_s");
}
TQString KviAmipInterface::artist()
{
return getAmipString("var_1");
}
TQString KviAmipInterface::title()
{
return getAmipString("var_2");
}
TQString KviAmipInterface::album()
{
return getAmipString("var_4");
}
TQString KviAmipInterface::year()
{
return getAmipString("var_5");
}
TQString KviAmipInterface::comment()
{
return getAmipString("var_6");
}
TQString KviAmipInterface::genre()
{
return getAmipString("var_7");
}
bool KviAmipInterface::setVol(kvs_int_t &iVol)
{
if(!amip_dll) return false;
char volcmd[AC_BUFFER_SIZE];
sprintf(volcmd, "control vol %d", iVol);
return (ac_exec(volcmd) == AC_ERR_NOERROR);
}
int KviAmipInterface::getVol()
{
return eval_int("var_vol");
}
bool KviAmipInterface::jumpTo(kvs_int_t &iPos)
{
if(!amip_dll) return false;
char jmpcmd[AC_BUFFER_SIZE];
sprintf(jmpcmd, "jumptotime %d", iPos/1000);
return (ac_exec(jmpcmd) == AC_ERR_NOERROR);
}
bool KviAmipInterface::hide()
{
HWND hWinamp = (HWND)eval_int("var_phwnd");
if(hWinamp && hWinamp != (HWND)-1)
{
ShowWindow(hWinamp, SW_HIDE);
return true;
}
return false;
}
bool KviAmipInterface::show()
{
HWND hWinamp = (HWND)eval_int("var_phwnd");
if(hWinamp && hWinamp != (HWND)-1)
{
ShowWindow(hWinamp, SW_SHOW);
return true;
}
return false;
}
bool KviAmipInterface::minimize()
{
if(!amip_dll) return false;
return (ac_exec("control mimimize") == AC_ERR_NOERROR);
}
bool KviAmipInterface::setPlayListPos(kvs_int_t &iPos)
{
if(!amip_dll) return false;
char jmpcmd[AC_BUFFER_SIZE];
sprintf(jmpcmd, "setplpos %d", iPos + 1);
return (ac_exec(jmpcmd) == AC_ERR_NOERROR);
}
int KviAmipInterface::getPlayListPos()
{
return eval_int("var_pos");
}
int KviAmipInterface::getListLength()
{
return eval_int("var_ll");
}
bool KviAmipInterface::getRepeat()
{
return eval_str("var_repeat").startsWith("on");
}
bool KviAmipInterface::getShuffle()
{
return eval_str("var_shuffle").startsWith("on");
}
bool KviAmipInterface::setShuffle(bool &bVal)
{
if(!amip_dll) return false;
bool res;
if (bVal)
{
res = (ac_exec("setshuffle on") == AC_ERR_NOERROR);
}
else
{
res = (ac_exec("setshuffle off") == AC_ERR_NOERROR);
}
return res;
}
bool KviAmipInterface::setRepeat(bool &bVal)
{
if(!amip_dll) return false;
bool res;
if (bVal)
{
res = (ac_exec("setrepeat on") == AC_ERR_NOERROR);
}
else
{
res = (ac_exec("setrepeat off") == AC_ERR_NOERROR);
}
return res;
}
bool KviAmipInterface::amipExec(const TQString &cmd)
{
if(!amip_dll) return false;
TQTextCodec *c=mediaplayer_get_codec();
KviStr szCmd = c ? c->fromUnicode(cmd) : cmd.utf8();
return (ac_exec(szCmd) == AC_ERR_NOERROR);
}
TQString KviAmipInterface::amipEval(const TQString &cmd)
{
TQString ret;
if(!amip_dll) return ret;
TQTextCodec *c=mediaplayer_get_codec();
KviStr szCmd = c ? c->fromUnicode(cmd) : cmd.utf8();
char buff[AC_BUFFER_SIZE];
if((ac_eval(szCmd, buff) == AC_ERR_NOERROR)) {
TQString s = buff;
TQTextCodec *c=mediaplayer_get_codec();
if (c) ret = c->toUnicode(s);
else ret=s;
}
return ret;
}
#endif //COMPILE_ON_WINDOWS