- 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
454 lines
12 KiB
C++
454 lines
12 KiB
C++
#include <windows.h>
|
|
#include <prsht.h>
|
|
#include <mmsystem.h>
|
|
#include <commctrl.h>
|
|
#include "resource.h"
|
|
#include "main.h"
|
|
|
|
extern HINSTANCE inst;
|
|
extern HWND hwnd;
|
|
|
|
extern char host[255], username[20], password[20];
|
|
extern int port, default_action, update_delay;
|
|
extern UINT timer_id;
|
|
extern bool use_auth;
|
|
|
|
extern char szAppName[], AboutText[];
|
|
|
|
extern HWND ConfigWnd, VolumeWnd;
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Entry point for new Config window, using Property Sheets instead of a single dialog.
|
|
void NewConfig()
|
|
{
|
|
PROPSHEETPAGE psp[4];
|
|
PROPSHEETHEADER psh;
|
|
|
|
psp[0].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[0].dwFlags = PSP_USEICONID | PSP_USETITLE;
|
|
psp[0].hInstance = inst;
|
|
psp[0].pszTemplate = MAKEINTRESOURCE(IDD_ABOUT);
|
|
psp[0].pszIcon = MAKEINTRESOURCE(IDI_WINAMP);
|
|
psp[0].pfnDlgProc = ConfigAboutWndProc;
|
|
psp[0].pszTitle = "About";
|
|
psp[0].lParam = 0;
|
|
psp[0].pfnCallback = NULL;
|
|
|
|
psp[1].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[1].dwFlags = PSP_USEICONID | PSP_USETITLE;
|
|
psp[1].hInstance = inst;
|
|
psp[1].pszTemplate = MAKEINTRESOURCE(IDD_SERVER);
|
|
psp[1].pszIcon = MAKEINTRESOURCE(IDI_SERVER);
|
|
psp[1].pfnDlgProc = ConfigServerWndProc;
|
|
psp[1].pszTitle = "Server";
|
|
psp[1].lParam = 0;
|
|
psp[1].pfnCallback = NULL;
|
|
|
|
psp[2].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[2].dwFlags = PSP_USEICONID | PSP_USETITLE;
|
|
psp[2].hInstance = inst;
|
|
psp[2].pszTemplate = MAKEINTRESOURCE(IDD_SYSTRAY);
|
|
psp[2].pszIcon = MAKEINTRESOURCE(GetIconID());
|
|
psp[2].pfnDlgProc = ConfigSystrayWndProc;
|
|
psp[2].pszTitle = "Tray Icon";
|
|
psp[2].lParam = 0;
|
|
psp[2].pfnCallback = NULL;
|
|
|
|
psp[3].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[3].dwFlags = PSP_USEICONID | PSP_USETITLE;
|
|
psp[3].hInstance = inst;
|
|
psp[3].pszTemplate = MAKEINTRESOURCE(IDD_AUTH);
|
|
psp[3].pszIcon = MAKEINTRESOURCE(IDI_AUTH2);
|
|
psp[3].pfnDlgProc = ConfigAuthWndProc;
|
|
psp[3].pszTitle = "Authentication";
|
|
psp[3].lParam = 0;
|
|
psp[3].pfnCallback = NULL;
|
|
|
|
|
|
psh.dwSize = sizeof(PROPSHEETHEADER);
|
|
psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE;
|
|
psh.hwndParent = hwnd;
|
|
psh.hInstance = inst;
|
|
psh.pszIcon = NULL;
|
|
psh.pszCaption = "WawiTray Config";
|
|
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
|
|
psh.nStartPage = 0;
|
|
psh.ppsp = (LPCPROPSHEETPAGE) &psp;
|
|
psh.pfnCallback = NULL;
|
|
|
|
PropertySheet(&psh);
|
|
config_write();
|
|
ConfigWnd = NULL;
|
|
return;
|
|
}
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Server options window proc
|
|
BOOL CALLBACK ConfigServerWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
char TempString[10];
|
|
int port_temp;
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
wsprintf(TempString,"%d",port);
|
|
SetDlgItemText(hwndDlg,IDC_HOST,host);
|
|
SetDlgItemText(hwndDlg,IDC_PORT,TempString);
|
|
break;
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
case PSN_APPLY: port_temp = GetDlgItemInt(hwndDlg,IDC_PORT,NULL,false);
|
|
if (port_temp > 0 && port_temp < 65536)
|
|
{
|
|
port = port_temp;
|
|
GetDlgItemText(hwndDlg,IDC_HOST,host,255);
|
|
}
|
|
else
|
|
{
|
|
MessageBox(hwndDlg,"Port must be from 1 to 65535!","Winamp Web Interface",MB_OK);
|
|
SetDlgItemInt(hwndDlg,IDC_PORT,port,false);
|
|
SetWindowLong(hwndDlg,DWL_MSGRESULT,true);
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Systray options window proc
|
|
BOOL CALLBACK ConfigSystrayWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
char temp[5];
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
int def_button;
|
|
switch(default_action)
|
|
{
|
|
case WA_PREV:
|
|
def_button = IDC_DEF_PREV;
|
|
break;
|
|
case WA_PLAY:
|
|
def_button = IDC_DEF_PLAY;
|
|
break;
|
|
case WA_PAUSE:
|
|
def_button = IDC_DEF_PAUSE;
|
|
break;
|
|
case WA_STOP:
|
|
def_button = IDC_DEF_STOP;
|
|
break;
|
|
case WA_NEXT:
|
|
def_button = IDC_DEF_NEXT;
|
|
break;
|
|
}
|
|
|
|
CheckRadioButton(hwndDlg,IDC_DEF_PREV,IDC_DEF_NEXT,def_button);
|
|
|
|
wsprintf(temp,"%d",update_delay);
|
|
SetDlgItemText(hwndDlg,IDC_UPDATEDELAY,temp);
|
|
break;
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
case PSN_APPLY: update_delay = GetDlgItemInt(hwndDlg,IDC_UPDATEDELAY,NULL,false);
|
|
KillTimer(hwnd,timer_id);
|
|
timer_id = SetTimer(hwnd,TIMER_ID,update_delay*1000,NULL);
|
|
if (IsDlgButtonChecked(hwndDlg,IDC_DEF_PREV) == BST_CHECKED)
|
|
default_action = WA_PREV;
|
|
else
|
|
if (IsDlgButtonChecked(hwndDlg,IDC_DEF_PREV) == BST_CHECKED)
|
|
default_action = WA_PREV;
|
|
else
|
|
if (IsDlgButtonChecked(hwndDlg,IDC_DEF_PLAY) == BST_CHECKED)
|
|
default_action = WA_PLAY;
|
|
else
|
|
if (IsDlgButtonChecked(hwndDlg,IDC_DEF_PAUSE) == BST_CHECKED)
|
|
default_action = WA_PAUSE;
|
|
else
|
|
if (IsDlgButtonChecked(hwndDlg,IDC_DEF_STOP) == BST_CHECKED)
|
|
default_action = WA_STOP;
|
|
else
|
|
default_action = WA_NEXT;
|
|
|
|
systray_modify(hwnd,1030,LoadIcon(inst, MAKEINTRESOURCE(GetIconID())),szAppName);
|
|
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Authentication options window proc
|
|
BOOL CALLBACK ConfigAuthWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
int use_auth_int;
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetDlgItemText(hwndDlg,IDC_USERNAME,username);
|
|
SetDlgItemText(hwndDlg,IDC_PASSWORD,password);
|
|
if (use_auth)
|
|
CheckDlgButton(hwndDlg,IDC_AUTH,1);
|
|
else
|
|
CheckDlgButton(hwndDlg,IDC_AUTH,0);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
case PSN_APPLY: GetDlgItemText(hwndDlg,IDC_USERNAME,username,20);
|
|
GetDlgItemText(hwndDlg,IDC_PASSWORD,password,20);
|
|
use_auth_int = IsDlgButtonChecked(hwndDlg,IDC_AUTH);
|
|
if (use_auth_int == 0)
|
|
use_auth = false;
|
|
else
|
|
use_auth = true;
|
|
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// About window proc
|
|
BOOL CALLBACK ConfigAboutWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
break;
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
case PSN_APPLY: break;
|
|
}
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// WindowProc for Config dialog
|
|
BOOL CALLBACK ConfigWndProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
ConfigWnd = hwndDlg; // Keep global pointer to window so no more than one is active
|
|
char temp[100];
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
int def_button;
|
|
switch(default_action)
|
|
{
|
|
case WA_PREV:
|
|
def_button = IDC_DEF_PREV;
|
|
break;
|
|
case WA_PLAY:
|
|
def_button = IDC_DEF_PLAY;
|
|
break;
|
|
case WA_PAUSE:
|
|
def_button = IDC_DEF_PAUSE;
|
|
break;
|
|
case WA_STOP:
|
|
def_button = IDC_DEF_STOP;
|
|
break;
|
|
case WA_NEXT:
|
|
def_button = IDC_DEF_NEXT;
|
|
break;
|
|
}
|
|
SetDlgItemText(hwndDlg,IDC_HOST,host);
|
|
wsprintf(temp,"%d",port);
|
|
SetDlgItemText(hwndDlg,IDC_PORT,temp);
|
|
wsprintf(temp,"%d",update_delay);
|
|
SetDlgItemText(hwndDlg,IDC_UPDATEDELAY,temp);
|
|
SetDlgItemText(hwndDlg,IDC_USERNAME,username);
|
|
SetDlgItemText(hwndDlg,IDC_PASSWORD,password);
|
|
CheckRadioButton(hwndDlg,IDC_DEF_PREV,IDC_DEF_NEXT,def_button);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDCANCEL: EndDialog(hwndDlg,0);
|
|
break;
|
|
case IDABOUT: MessageBox(hwnd,AboutText,szAppName,MB_OK | MB_ICONINFORMATION);
|
|
break;
|
|
case IDOK: GetDlgItemText(hwndDlg,IDC_HOST,host,255);
|
|
port = GetDlgItemInt(hwndDlg,IDC_PORT,NULL,false);
|
|
update_delay = GetDlgItemInt(hwndDlg,IDC_UPDATEDELAY,NULL,false);
|
|
KillTimer(hwnd,timer_id);
|
|
timer_id = SetTimer(hwnd,TIMER_ID,update_delay*1000,NULL);
|
|
GetDlgItemText(hwndDlg,IDC_USERNAME,username,20);
|
|
GetDlgItemText(hwndDlg,IDC_PASSWORD,password,20);
|
|
if (IsDlgButtonChecked(hwndDlg,IDC_DEF_PREV) == BST_CHECKED)
|
|
default_action = WA_PREV;
|
|
else
|
|
if (IsDlgButtonChecked(hwndDlg,IDC_DEF_PREV) == BST_CHECKED)
|
|
default_action = WA_PREV;
|
|
else
|
|
if (IsDlgButtonChecked(hwndDlg,IDC_DEF_PLAY) == BST_CHECKED)
|
|
default_action = WA_PLAY;
|
|
else
|
|
if (IsDlgButtonChecked(hwndDlg,IDC_DEF_PAUSE) == BST_CHECKED)
|
|
default_action = WA_PAUSE;
|
|
else
|
|
if (IsDlgButtonChecked(hwndDlg,IDC_DEF_STOP) == BST_CHECKED)
|
|
default_action = WA_STOP;
|
|
else
|
|
default_action = WA_NEXT;
|
|
|
|
systray_modify(hwnd,1030,LoadIcon(inst, MAKEINTRESOURCE(GetIconID())),szAppName);
|
|
config_write();
|
|
EndDialog(hwndDlg,0);
|
|
break;
|
|
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// write config
|
|
void config_write()
|
|
{
|
|
char ini_file[MAX_PATH], *p;
|
|
char string[32];
|
|
GetModuleFileName(inst,ini_file,sizeof(ini_file));
|
|
p=ini_file+lstrlen(ini_file);
|
|
while (p >= ini_file && *p != '\\') p--;
|
|
if (++p >= ini_file) *p = 0;
|
|
lstrcat(ini_file,"client.ini");
|
|
|
|
wsprintf(string,"%d",port);
|
|
WritePrivateProfileString(szAppName,"port",string,ini_file);
|
|
|
|
wsprintf(string,"%d",default_action);
|
|
WritePrivateProfileString(szAppName,"default",string,ini_file);
|
|
|
|
wsprintf(string,"%d",update_delay);
|
|
WritePrivateProfileString(szAppName,"updatedelay",string,ini_file);
|
|
|
|
if (use_auth)
|
|
WritePrivateProfileString(szAppName,"auth","1",ini_file);
|
|
else
|
|
WritePrivateProfileString(szAppName,"auth","0",ini_file);
|
|
|
|
|
|
WritePrivateProfileString(szAppName,"host",host,ini_file);
|
|
WritePrivateProfileString(szAppName,"username",username,ini_file);
|
|
WritePrivateProfileString(szAppName,"password",password,ini_file);
|
|
|
|
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// read config (port and password)
|
|
void config_read()
|
|
{
|
|
char ini_file[MAX_PATH], *p;
|
|
GetModuleFileName(inst,ini_file,sizeof(ini_file));
|
|
p=ini_file+lstrlen(ini_file);
|
|
while (p >= ini_file && *p != '\\') p--;
|
|
if (++p >= ini_file) *p = 0;
|
|
lstrcat(ini_file,"client.ini");
|
|
|
|
GetPrivateProfileString(szAppName,"host","127.0.0.1",(char*)&host,255,ini_file);
|
|
GetPrivateProfileString(szAppName,"username","user",(char*)&username,20,ini_file);
|
|
GetPrivateProfileString(szAppName,"password","password",(char*)&password,20,ini_file);
|
|
|
|
port = GetPrivateProfileInt(szAppName,"port",80,ini_file);
|
|
default_action = GetPrivateProfileInt(szAppName,"default",WA_NEXT,ini_file);
|
|
update_delay = GetPrivateProfileInt(szAppName,"updatedelay",10,ini_file);
|
|
|
|
int use_auth_int = GetPrivateProfileInt(szAppName,"auth",0,ini_file);
|
|
if (use_auth_int == 1)
|
|
use_auth = true;
|
|
else
|
|
use_auth = false;
|
|
|
|
}
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// WindowProc for Volume dialog
|
|
BOOL CALLBACK VolumeWndProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
char temp[50];
|
|
VolumeWnd = hwndDlg;
|
|
HWND SliderWnd;
|
|
POINT mousepos;
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
GetCursorPos(&mousepos);
|
|
SetWindowPos(hwndDlg,HWND_TOP,mousepos.x-46,mousepos.y-95,0,0,SWP_NOSIZE);
|
|
SliderWnd = GetDlgItem(hwndDlg,IDC_VOLUME);
|
|
SendMessage(SliderWnd, TBM_SETRANGE, (WPARAM) true, (LPARAM) MAKELONG(0,10));
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_DONE:
|
|
EndDialog(hwndDlg,0);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_VSCROLL:
|
|
DWORD dwPos;
|
|
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case TB_THUMBTRACK:
|
|
case TB_LINEDOWN:
|
|
case TB_LINEUP:
|
|
case TB_PAGEDOWN:
|
|
case TB_PAGEUP:
|
|
|
|
SliderWnd = GetDlgItem(hwndDlg,IDC_VOLUME);
|
|
dwPos = SendMessage(SliderWnd, TBM_GETPOS, 0, 0);
|
|
wsprintf(temp,"/vol?volume=%d",10-dwPos);
|
|
//MessageBox(SliderWnd,temp,"Slider Position",MB_OK | MB_TOPMOST);
|
|
WASend(temp);
|
|
return 0;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|