Files
winamp-mpris/Wawi Source/op_winamp.cpp
ergosteur 22492dbee9 Implement XDG compliance, logging, and improved 401 error handling
- Install to ~/.local/bin/winamp-mpris
- Use ~/.local/state/winamp-mpris/bridge.log for logging
- Use $XDG_RUNTIME_DIR/winamp-mpris.pid for PID management
- Add detailed user notification for 401 Unauthorized errors
- Add install.sh for automated, standard-compliant setup
- Include Winamp Web Interface source code and installer in repository
2026-04-08 18:29:40 -04:00

1027 lines
28 KiB
C++

/* --- OP_WINAMP.CPP ---
/
/ Written by Phil Himsworth, 2001-2002.
/
/*/
#include <windows.h>
#include "types.h"
#include "main.h"
#include "plugin.h"
#include "html.h"
#include "wamessage.h"
#include "op_winamp.h"
#include "resource.h"
extern char mp3root[MAX_PATH], playlistdir[MAX_PATH], logfiledir[MAX_PATH], filetypes[255];
extern int browse_enable, dl_wa_files, dl_other_files, show_other_files, frames, title_refresh, securepassword;
extern char szAppVer[];
extern char pagetitle[255];
extern winampGeneralPurposePlugin plugin;
// --------------------------------------------------------------------------------
// Send an image from a resource
int CControl::Image(connection * conn,int type)
{
//char * img = &conn->http.file[5];
char img[30];
GetArgValue(conn,"image",(char*)&img,30);
//MessageBox(NULL,img,"gen_httpSrv debug",MB_OK | MB_TOPMOST);
int imageid = atoi2(img);
char dll[MAX_PATH];
GetModuleFileName(plugin.hDllInstance,dll,sizeof(dll));
HMODULE hm = GetModuleHandle(dll);
if (hm == NULL)
MessageBox(NULL,"gmh failed","gen_httpSrv debug",MB_OK);
HRSRC resimage = FindResource(hm,MAKEINTRESOURCE(imageid),"Image");
if (!resimage) // after an image that doesn't exist
{
//MessageBox(NULL,"Bad image","gen_httpSrv debug",MB_OK);
return ST_CLOSE;
//closesocket(conn.socket);
//return true;
}
HGLOBAL image = LoadResource(hm, resimage);
DWORD imglen = SizeofResource(hm, resimage);
switch(type)
{
case IMG_GIF:
OpenHTTPHeader(conn,"image/gif",(int)imglen,NULL);
break;
case IMG_ICO:
OpenHTTPHeader(conn,"image/x-icon",(int)imglen,NULL);
break;
}
if(conn->http.reqID == RID_HEAD)
return ST_CLOSE;
flush(conn);
send(conn->socket,(char*)image,imglen,0);
return ST_CLOSE;
}
// --------------------------------------------------------------------------------
// Sends top frame with buttons and the like
int CControl::TopFrame(connection * conn)
{
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
CloseHeader(conn);
OpenHeaderBody(conn);
LinkTable(conn);
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Tiny title
int CControl::SmallTitle(connection * conn)
{
conn->log = false;
OpenHTTPHeader(conn,"text/plain",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
SongInfo(conn);
prints(conn,"\n\n");
return ST_CLOSE;
}
// --------------------------------------------------------------------------------
// Sends full title information
int CControl::Title(connection * conn)
{
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
else
{
OpenHtmlHeader(conn);
prints(conn,"<meta http-equiv=\"Refresh\" content=\"");
printsi(conn,title_refresh);
prints(conn,"; url=/title\">\n");
Style(conn);
CloseHeader(conn);
OpenPageBody(conn);
FullSongInfo(conn);
prints(conn,"\n");
return ST_CLOSEBODY;
}
}
// --------------------------------------------------------------------------------
// Shuts down winamp and the computer, in theory. Doesn't, though...
int CControl::Shutdown(connection * conn)
{
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
Style(conn);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Turning off...</p>\n");
ExitWindows(0,0);
PostMessage(WAwnd(),WM_CLOSE,0,0);
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Clears playlist
int CControl::Clear(connection * conn)
{
SendMessage(WAwnd(),WM_USER,0,WAU_CLEARPLIST);
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
Style(conn);
RefreshHeader(conn,"/list");
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Playlist cleared</p>\n");
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Download a song
int CControl::Download(connection * conn)
{
// exactly the same filename processing as Load, below.
char filepath[MAX_PATH];
GetArgValue(conn,"file",filepath,MAX_PATH);
//char *relfilepath = &conn->http.file[4];
Unescape_url(filepath);
ReplaceSlashes(filepath);
if (!GoodPath(filepath))
ReportError(conn,"<p>The path requested is illegal.</p>\n<p>It cotains the <b>..</b> directory, which could present a security risk.</p>\n");
else
{
bool wafile = IsWinampFile(GetFilename(filepath));
if ((wafile && dl_wa_files==0) || (!wafile && dl_other_files==0))
ReportError(conn,"<p>Downloading files of this type is not permitted from this server.</p>");
else
{
char fullfilepath[MAX_PATH];
int pathlen = wsprintf(fullfilepath,"%s%s",mp3root,filepath);
Unescape_url((char*)&fullfilepath);
/*
- Open a header with the right MIME type - needs file size
- Call TransmitFile()
- Rockin'.
*/
HANDLE hFile = CreateFile( fullfilepath,
GENERIC_READ,
0,
0,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
0);
if (hFile == INVALID_HANDLE_VALUE)
ReportError(conn,"<p>Couldn't open the file.</p>\n<p>Check the file exists and the name is correct.</p>\n");
else
{
DWORD dwSize = GetFileSize(hFile, NULL);
OpenHTTPHeader(conn,"audio/mpeg",dwSize,GetFilename(fullfilepath));
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
flush(conn);
TransmitFile(conn->socket, hFile, dwSize, 0, NULL, NULL, NULL);
CloseHandle(hFile);
return ST_CLOSE;
}
}
}
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Load a song into the playlist
int CControl::Load(connection * conn)
{
char relfilepath[MAX_PATH];
char filepath[MAX_PATH];
char shortcutfilepath[MAX_PATH];
char playmode[10];
GetArgValue(conn,"path",relfilepath,MAX_PATH);
Unescape_url(relfilepath);
char refreshto[MAX_PATH];
if (relfilepath[0] == '\\' && relfilepath[1] != '\\') // single slash - local file (not UNC '\\' or HTTP 'http://...')
{
if (!GoodPath(relfilepath))
{
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
Style(conn);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p><b>Error!</b> The path requested is illegal.</p>\n");
prints(conn,"<p>&nbsp;</p>\n");
return ST_CLOSEBODY;
}
else // Local path is okay
{
// need to check whether it's a url shortcut file
fileinfo file;
lstrcpy(file.name,relfilepath);
IsWinampFile(&file);
if (file.urlsct) // url shortcut; load contained address into 'filepath'
{
wsprintf(shortcutfilepath,"%s%s",mp3root,relfilepath);
GetPrivateProfileString("InternetShortcut","URL","",filepath,MAX_PATH,shortcutfilepath);
}
else // not a shortcut; just put the right path into filepath
{
wsprintf(filepath,"%s%s",mp3root,relfilepath);
}
// refresh to "/browse?path=<directory containing file>"
char * p;
if (frames == 3)
wsprintf(refreshto,"/title");
else
{
char refreshtemp[MAX_PATH];
wsprintf(refreshtemp,"%s",relfilepath);
p=refreshtemp+lstrlen(refreshtemp);
while (p >= refreshtemp && *p != '\\') p--;
if (++p >= refreshtemp) *p = 0;
Escape_url(refreshtemp);
wsprintf(refreshto,"/browse?path=%s",refreshtemp);
}
}
}
else // HTTP or UNC name; load directly
{
wsprintf(filepath,"%s",relfilepath);
}
//MessageBox(NULL,filepath,"filepath",MB_OK | MB_TOPMOST);
int pathlen = lstrlen(filepath);
COPYDATASTRUCT cds;
cds.dwData = IPC_PLAYFILE;
cds.lpData = (void *)&filepath;
cds.cbData = pathlen+1;
SendMessage(WAwnd(),WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds);
if (GetArgValue(conn,"play",playmode,10))
{
if (StrComp(playmode,"now"))
{
int pl_len = SendMessage(WAwnd(),WM_USER,0,WAU_PLCOUNT);
SendMessage(WAwnd(),WM_USER,pl_len-1,WAU_SETPLPOS);
SendMessage(WAwnd(),WM_COMMAND,WAC_PLAY,0);
}
}
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
GetArgValue(conn,"refresh",refreshto,10); // will overwrite existing value if
// the param exists
OpenHtmlHeader(conn);
Style(conn);
RefreshHeader(conn,refreshto);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Load file command sent: &nbsp; <b>");
prints(conn,relfilepath); // actually relfilepath
prints(conn,"</b></p>\n");
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Send playlist page
int CControl::List(connection * conn)
{
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
Style(conn);
CloseHeader(conn);
OpenPageBody(conn);
if (frames == 1)
LinkBar(conn);
prints(conn,"<h3>\n<i>\n... Current Playlist ...\n</i></h3>\n");
prints(conn,"<form action=\"/list\" method=\"get\">\n");
prints(conn,"Show only songs containing: <input type=\"text\" name=\"sub\" size=\"30\">\n");
prints(conn,"<input type=\"submit\" value=\"Search\">\n");
prints(conn,"</form>\n");
prints(conn,"<h6>\n<a href=\"#current\">Jump to Current Track</a>&nbsp;|&nbsp;");
prints(conn,"<a href=\"/sort\">Sort Playlist</a>&nbsp;|&nbsp;<a href=\"/clear\">Clear Playlist</a>");
prints(conn,"&nbsp;|&nbsp;<a href=\"save\">Save Playlist</a></h6>\n<ol>\n");
char song[255], lcasesong[255], substring[255];
bool restrict = GetArgValue(conn,"sub",substring,255); // search for substring?
if (restrict && substring[0] == 0) // if it's blank, show all
restrict = false;
if (restrict)
{
Unescape_url(substring);
CharLower(substring);
prints(conn,"<p>Showing songs containing: ");
prints(conn,substring);
prints(conn,"</p>\n");
}
prints(conn,"<ol>\n");
int current = SendMessage(WAwnd(),WM_USER, 0, WAU_GETPLPOS);
char tbuffer[255];
int t = SendMessage(WAwnd(),WM_USER, 0, WAU_PLCOUNT);
for (int count=0;count<t;count++)
{
lstrcpy(song,(char*)SendMessage(WAwnd(),WM_USER, count, WAU_GETTITLE));
lstrcpy(lcasesong,song);
CharLower(lcasesong);
if (strstr2(lcasesong,substring) || restrict == false)
{
if (count == current)
prints(conn,"<b><a name=\"current\"></a>");
prints(conn,"<li>");
wsprintf(tbuffer,"/delete?track=%d",count+1);
ImgLink(conn,tbuffer,IDR_IMG_LIST_DEL,"Remove",0,0,T_MAIN);
wsprintf(tbuffer,"/play?track=%d",count+1);
ImgLink(conn,tbuffer,IDR_IMG_LIST_PLAY,"Play",0,0,T_BOTTOM);
if (frames == 3)
wsprintf(tbuffer,"<a href=\"/play?track=%d\" target=\"bottom\">%s</a></li>\n", count+1, song);
else
wsprintf(tbuffer,"<a href=\"/play?track=%d\" >%s</a></li>\n", count+1, song);
prints(conn,tbuffer);
if (count == current)
prints(conn,"</b>");
}
}
prints(conn,"</ol>\n</p>");
if (frames == 1)
LinkBar(conn);
prints(conn,"<p>&nbsp;</p>");
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Next track
int CControl::Next(connection * conn)
{
SendMessage(WAwnd(),WM_COMMAND,WAC_NEXT,0);
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
Style(conn);
char refreshto[MAX_PATH];
if (!GetArgValue(conn,"refresh",refreshto,10))
{
if (frames == 3)
wsprintf(refreshto,"/title");
else
wsprintf(refreshto,"/main");
}
RefreshHeader(conn,refreshto);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Next track command sent</p>\n");
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Previous track
int CControl::Prev(connection * conn)
{
SendMessage(WAwnd(),WM_COMMAND,WAC_PREV,0);
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
char refreshto[MAX_PATH];
if (!GetArgValue(conn,"refresh",refreshto,10))
{
if (frames == 3)
wsprintf(refreshto,"/title");
else
wsprintf(refreshto,"/main");
}
RefreshHeader(conn,refreshto);
Style(conn);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Previous track command sent</p>\n");
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Start playback
int CControl::Play(connection * conn)
{
char strtrack[10];
if (GetArgValue(conn,"track",strtrack,10))
{
int track = atoi2(strtrack) - 1;
if (track >= 0)
SendMessage(WAwnd(),WM_USER,track,WAU_SETPLPOS);
}
SendMessage(WAwnd(),WM_COMMAND,WAC_PLAY,0);
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
Style(conn);
char refreshto[MAX_PATH];
if (!GetArgValue(conn,"refresh",refreshto,10))
{
if (frames == 3)
wsprintf(refreshto,"/title");
else
wsprintf(refreshto,"/main");
}
RefreshHeader(conn,refreshto);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Play command sent</p>\n");
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Stop playback
int CControl::Stop(connection * conn)
{
SendMessage(WAwnd(),WM_COMMAND,WAC_STOP,0);
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
char refreshto[MAX_PATH];
if (!GetArgValue(conn,"refresh",refreshto,10))
{
if (frames == 3)
wsprintf(refreshto,"/title");
else
wsprintf(refreshto,"/main");
}
RefreshHeader(conn,refreshto);
Style(conn);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Stop command sent</p>\n");
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Stop with fadeout
int CControl::StopSlow(connection * conn)
{
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
char refreshto[MAX_PATH];
if (!GetArgValue(conn,"refresh",refreshto,10))
{
if (frames == 3)
wsprintf(refreshto,"/title");
else
wsprintf(refreshto,"/main");
}
RefreshHeader(conn,refreshto);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Stopping...");
flush(conn);
SendMessage(WAwnd(),WM_COMMAND,WAC_STOPFADE,0);
prints(conn," OK!</p>\n");
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Pause. Why am I even bothering to comment these?!?
int CControl::Pause(connection * conn)
{
SendMessage(WAwnd(),WM_COMMAND,WAC_PAUSE,0);
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
char refreshto[MAX_PATH];
if (!GetArgValue(conn,"refresh",refreshto,10))
{
if (frames == 3)
wsprintf(refreshto,"/title");
else
wsprintf(refreshto,"/main");
}
RefreshHeader(conn,refreshto);
Style(conn);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Pause command sent</p>\n");
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Change volume
int CControl::Volume(connection * conn)
{
char strvol[20];
GetArgValue(conn,"volume",strvol,20);
int vol = atoi2(strvol); // Mwuahaha, die Clib
vol = (int)(vol * 25.5);
SendMessage(WAwnd(),WM_USER,vol,122);
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
Style(conn);
char refreshto[MAX_PATH];
if (!GetArgValue(conn,"refresh",refreshto,10))
{
if (frames == 3)
wsprintf(refreshto,"/title");
else
wsprintf(refreshto,"/main");
}
RefreshHeader(conn,refreshto);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Change volume command sent</p>\n");
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Change repeat / random modes
int CControl::Playmode(connection * conn)
{
char repeat[10], random[10];
if (!GetArgValue(conn,"repeat",repeat,10))
wsprintf(repeat,"none");
if (!GetArgValue(conn,"random",random,10))
wsprintf(random,"none");
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
Style(conn);
char refreshto[MAX_PATH];
if (!GetArgValue(conn,"refresh",refreshto,10))
wsprintf(refreshto,"/main");
RefreshHeader(conn,refreshto);
CloseHeader(conn);
OpenPageBody(conn);
if (StrComp(repeat,"on"))
{
SendMessage(WAwnd(),WM_USER,1,WAU_SETREPEAT);
prints(conn,"<p>Repeat set to <b>ON</b></p>");
}
if (StrComp(repeat,"off"))
{
SendMessage(WAwnd(),WM_USER,0,WAU_SETREPEAT);
prints(conn,"<p>Repeat set to <b>OFF</b></p>");
}
if (StrComp(repeat,"toggle"))
{
SendMessage(WAwnd(),WM_COMMAND,WAC_REPEATT,0);
prints(conn,"<p>Repeat toggled</p>");
}
if (StrComp(random,"on"))
{
SendMessage(WAwnd(),WM_USER,1,WAU_SETRANDOM);
prints(conn,"<p>Random set to <b>ON</b></p>");
}
if (StrComp(random,"off"))
{
SendMessage(WAwnd(),WM_USER,0,WAU_SETRANDOM);
prints(conn,"<p>Random set to <b>OFF</b></p>");
}
if (StrComp(random,"toggle"))
{
SendMessage(WAwnd(),WM_COMMAND,WAC_RANDOMT,0);
prints(conn,"<p>Random toggled</p>");
}
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// About box
int CControl::About(connection * conn)
{
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
Style(conn);
CloseHeader(conn);
prints(conn,"<body>\n");
prints(conn,"<p align=center><b>Winamp Web Interface</b><br>\nVersion ");
prints(conn,szAppVer);
prints(conn,"</p>\n");
prints(conn,"<p align=center>\n<i>\nPhil Himsworth 2002<br>\n");
prints(conn,"<a href=mailto:contact@flippet.net>contact@flippet.net</a>&nbsp;&middot;&nbsp;<a href=http://www.flippet.net target=\"AnotherWindow\">www.flippet.net</a>\n</i>\n</p>\n\n");
prints(conn,"</body>\n");
flush(conn);
closesocket(conn->socket);
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Main window
int CControl::Main(connection * conn)
{
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
Style(conn);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<h1 align=center>\n<i>\n");
prints(conn,pagetitle);
prints(conn,"\n</i>\n\n</h1>\n");
prints(conn,"<h6 align=center>\n<a href=\"JavaScript:about()\">About Winamp Web Interface v.");
prints(conn,szAppVer);
prints(conn,"</a></h6>");
prints(conn,"<hr>\n");
prints(conn,"<h3>\n<i>\n... Winamp Status ...\n</i></h3>\n");
prints(conn,"<p>\n");
FullSongInfo(conn);
prints(conn,"</p>\n");
int repeat = SendMessage(WAwnd(),WM_USER,0,WAU_GETREPEAT);
int random = SendMessage(WAwnd(),WM_USER,0,WAU_GETRANDOM);
prints(conn,"<p>Repeat is ");
if (repeat == 1)
prints(conn,"<b>on</b> ");
if (repeat == 0)
prints(conn,"<b>off</b> ");
prints(conn,"[ ");
Link(conn,"/playmode?repeat=on","on",T_NONE);
prints(conn," | ");
Link(conn,"/playmode?repeat=off","off",T_NONE);
prints(conn," | ");
Link(conn,"/playmode?repeat=toggle","toggle",T_NONE);
prints(conn," ]");
prints(conn,"<br>Random is ");
if (random == 1)
prints(conn,"<b>on</b> ");
if (random == 0)
prints(conn,"<b>off</b> ");
prints(conn,"[ ");
Link(conn,"/playmode?random=on","on",T_NONE);
prints(conn," | ");
Link(conn,"/playmode?random=off","off",T_NONE);
prints(conn," | ");
Link(conn,"/playmode?random=toggle","toggle",T_NONE);
prints(conn," ]");
prints(conn,"</p>\n");
if (frames == 1)
LinkBar(conn);
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// PDA mode - small
int CControl::pda(connection * conn)
{
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
Style(conn);
CloseHeader(conn);
prints(conn,"<body bgcolor=\"#000000\">\n");
prints(conn,"<p align=\"center\">\n");
ImgLink(conn,"/prev?refresh=pda",IDR_IMG_PREV,"Previous Track",0,0,T_NONE);
Img(conn,IDR_IMG_BLACK,"",2,30);
ImgLink(conn,"/play?refresh=pda",IDR_IMG_PLAY,"Play",0,0,T_NONE);
Img(conn,IDR_IMG_BLACK,"",2,30);
ImgLink(conn,"/pause?refresh=pda",IDR_IMG_PAUSE,"Pause",0,0,T_NONE);
Img(conn,IDR_IMG_BLACK,"",2,30);
ImgLink(conn,"/stop?refresh=pda",IDR_IMG_STOP,"Stop",0,0,T_NONE);
Img(conn,IDR_IMG_BLACK,"",2,30);
ImgLink(conn,"/next?refresh=pda",IDR_IMG_NEXT,"Next Track",0,0,T_NONE);
prints(conn,"</p>\n<p align=\"center\">\n");
// Volume control links
ImgLink(conn,"/vol?volume=0&refresh=pda",IDR_VOL_00,"0/10",0,0,T_NONE);
ImgLink(conn,"/vol?volume=1&refresh=pda",IDR_VOL_01,"1/10",0,0,T_NONE);
ImgLink(conn,"/vol?volume=2&refresh=pda",IDR_VOL_02,"2/10",0,0,T_NONE);
ImgLink(conn,"/vol?volume=3&refresh=pda",IDR_VOL_03,"3/10",0,0,T_NONE);
ImgLink(conn,"/vol?volume=4&refresh=pda",IDR_VOL_04,"4/10",0,0,T_NONE);
ImgLink(conn,"/vol?volume=5&refresh=pda",IDR_VOL_05,"5/10",0,0,T_NONE);
ImgLink(conn,"/vol?volume=6&refresh=pda",IDR_VOL_06,"6/10",0,0,T_NONE);
ImgLink(conn,"/vol?volume=7&refresh=pda",IDR_VOL_07,"7/10",0,0,T_NONE);
ImgLink(conn,"/vol?volume=8&refresh=pda",IDR_VOL_08,"8/10",0,0,T_NONE);
ImgLink(conn,"/vol?volume=9&refresh=pda",IDR_VOL_09,"9/10",0,0,T_NONE);
ImgLink(conn,"/vol?volume=10&refresh=pda",IDR_VOL_10,"10/10",0,0,T_NONE);
prints(conn,"\n</p>\n<p align=\"center\">\n");
int repeat = SendMessage(WAwnd(),WM_USER,0,WAU_GETREPEAT);
int random = SendMessage(WAwnd(),WM_USER,0,WAU_GETRANDOM);
if (repeat)
ImgLink(conn,"/playmode?repeat=toggle&refresh=pda",IDR_IMG_RPT_ON,"Toggle Repeat",0,0,T_NONE);
else
ImgLink(conn,"/playmode?repeat=toggle&refresh=pda",IDR_IMG_RPT_OFF,"Toggle Repeat",0,0,T_NONE);
if (random)
ImgLink(conn,"/playmode?random=toggle&refresh=pda",IDR_IMG_RND_ON,"Toggle Random",0,0,T_NONE);
else
ImgLink(conn,"/playmode?random=toggle&refresh=pda",IDR_IMG_RND_OFF,"Toggle Random",0,0,T_NONE);
prints(conn,"</p>\n");
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Delete playlist entry. Uses DeletePlaylistEntry2()
int CControl::Delete(connection * conn) // using Playlist Window message
{
char strtrack[20];
GetArgValue(conn,"track",strtrack,20);
int track = atoi2(strtrack);
return DeletePlaylistEntry2(conn,track-1);
}
// --------------------------------------------------------------------------------
// Returns wawi.css
int CControl::UserStyle(connection * conn)
{
OpenHTTPHeader(conn,"text/plain",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
char style_file[MAX_PATH], *p;
GetModuleFileName(plugin.hDllInstance,style_file,sizeof(style_file));
p=style_file+lstrlen(style_file);
while (p >= style_file && *p != '\\') p--;
if (++p >= style_file) *p = 0;
lstrcat(style_file,"wawi.css");
HANDLE hFile = CreateFile( style_file,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
prints(conn,"BODY\n{\nFONT-FAMILY: arial,sans-serif\n}\nA:link\n{\nCOLOR: blue;\nTEXT-DECORATION: none\n}\nA:visited\n{\nCOLOR: blue;\nTEXT-DECORATION: none\n}\nA:active\n{\nCOLOR: #ff9050;\nTEXT-DECORATION: none\n}\nA:hover\n{\nCOLOR: #e4a029;\nTEXT-DECORATION: none\n}\n\n");
return ST_CLOSE;
}
DWORD dwSize = GetFileSize(hFile, NULL);
flush(conn);
TransmitFile(conn->socket, hFile, dwSize, 0, NULL, NULL, NULL);
CloseHandle(hFile);
prints(conn,"\n\n");
return ST_CLOSE;
}
// --------------------------------------------------------------------------------
// Sorts playlist
int CControl::Sort(connection * conn)
{
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
char refreshto[MAX_PATH];
if (!GetArgValue(conn,"refresh",refreshto,10))
wsprintf(refreshto,"/list");
RefreshHeader(conn,refreshto);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Sorting...");
flush(conn);
HWND playlistwnd = FindWindow("Winamp PE","Winamp Playlist Editor");
if (playlistwnd == NULL)
prints(conn,"<b>Error</b>: Couldn't find Winamp Playlist window...</p>");
else
{
SendMessage(playlistwnd,WM_COMMAND,PLC_SORTTITLE,0);
prints(conn," OK!</p>\n");
}
return ST_CLOSEBODY;
}
// --------------------------------------------------------------------------------
// Saves playlist
int CControl::SavePlaylist(connection * conn)
{
OpenHTTPHeader(conn,"text/html",0,NULL);
if (conn->http.reqID == RID_HEAD)
return ST_CLOSE;
OpenHtmlHeader(conn);
Style(conn);
char location[MAX_PATH];
char nicelocation[MAX_PATH];
char fulllocation[MAX_PATH];
// see if a location is specified; ask if not
if (!GetArgValue(conn,"location",location,MAX_PATH))
{
// no location; pop up form
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<h3><i>... Save Playlist ... </i></h3>\n");
prints(conn,"<form action=\"/save\" method=\"get\">\n");
prints(conn,"<p> Playlist Name: <input type=\"text\" name=\"location\" size=\"40\">\n");
prints(conn,"<input type=\"submit\" value=\"Save\"></p>\n");
prints(conn,"</form>\n");
prints(conn,"<p>&nbsp;</p>\n");
Link(conn,"/list","Return to Playlist",T_NONE);
}
else
{
char refreshto[MAX_PATH];
if (!GetArgValue(conn,"refresh",refreshto,10))
wsprintf(refreshto,"/list");
// location given; save it to mp3root \ playlist directory \ location
int dirlen = strlen(playlistdir);
if (dirlen == 0)
wsprintf(nicelocation,"%s.m3u",location);
else
wsprintf(nicelocation,"%s\\%s.m3u",playlistdir,location);
wsprintf(fulllocation,"%s\\%s",mp3root,nicelocation);
//MessageBox(NULL,fulllocation,nicelocation,MB_OK | MB_TOPMOST);
SendMessage(WAwnd(),WM_USER,0,WAU_PLSAVE);
// Find winamp.m3u; it's in the same dir as exe of current process.
DWORD wapid = GetWindowThreadProcessId(WAwnd(),NULL);
HMODULE hMod = (HMODULE)OpenProcess(PROCESS_ALL_ACCESS,false,wapid);
char playlistfile[MAX_PATH], *p;
GetModuleFileName(hMod,playlistfile,sizeof(playlistfile));
CloseHandle(hMod);
// Make \path\winamp.exe into \path\winamp.m3u
p=playlistfile+lstrlen(playlistfile);
while (p >= playlistfile && *p != '\\') p--;
if (++p >= playlistfile) *p = 0;
lstrcat(playlistfile,"winamp.m3u");
if (CopyFile(playlistfile,fulllocation,true) == 0)
{
// function failed; try again
if (CopyFile(playlistfile,fulllocation,false) == 0)
{
// failed totally; tell them
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p><b>Error!</b></p><p>Couldn't save the playlist to <b>");
prints(conn,nicelocation);
prints(conn,"</b></p>\n<p>Does the directory exist?</p>");
Link(conn,"list","Back to Playlist",T_NONE);
}
else
{
// file overwritten
RefreshHeader(conn,refreshto);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Playlist saved to <b>");
prints(conn,nicelocation);
prints(conn,"<b>\n<p>Previous playlist overwritten.</p>\n");
}
}
else
{
// file copied ok
RefreshHeader(conn,refreshto);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"<p>Playlist saved to <b>");
prints(conn,nicelocation);
prints(conn,"</b></p>\n");
}
}
if (frames == 1)
LinkBar(conn);
return ST_CLOSEBODY;
}