1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-06-30 06:35:23 +00:00
icecast-server/win32/Icecast2winDlg.cpp
Karl Heyes 0868602bc0 win32 update. change build settings so that we make the process simpler, it
was very easy for the intermediate files to clash between projects.  The newer
libxml2/libxslt/libcurl also were causing some threading issues due to
library initialization


svn path=/icecast/trunk/icecast/; revision=14465
2008-02-11 01:00:41 +00:00

1208 lines
32 KiB
C++

// Icecast2winDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Icecast2win.h"
#include "Icecast2winDlg.h"
#include <process.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <stdlib.h>
#include <curl/curl.h>
extern "C" {
#include "thread/thread.h"
#include "avl/avl.h"
#include "log/log.h"
#include "global.h"
#include "httpp/httpp.h"
#include "net/sock.h"
#include "connection.h"
#include "refbuf.h"
#include "client.h"
#include "stats.h"
#include "xslt.h"
}
#include <afxinet.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define ICECAST_VERSION "2.x"
CEdit *g_accessControl;
CEdit *g_errorControl;
CIcecast2winDlg *g_mainDialog;
bool g_tailAccess = false;
bool g_tailError = false;
CString gConfigurationSave;
char gTitleSource[1024] = "";
char gTitleName[1024] = "";
#define MAXSTATSPERSOURCE 60
#define MAXSOURCES 1024
typedef struct tagElement {
CString name;
CString value;
int titleFlag;
} Element;
typedef struct tagElementAdditional {
CString source;
CString name;
CString value;
int titleFlag;
} ElementAdditional;
typedef struct tagMainElement {
CString source;
long numStats;
Element stats[MAXSTATSPERSOURCE];
int populated;
} MainElement;
typedef struct tagMainElementAdditional {
long numStats;
ElementAdditional stats[MAXSTATSPERSOURCE];
} MainElementAdditional;
MainElement gStats[MAXSOURCES];
MainElement gGlobalStats;
MainElementAdditional gAdditionalGlobalStats;
long numMainStats;
extern "C" {
int main(int argc, char **argv);
}
void AddToAdditionalGlobalStats(CString source, CString name) {
int foundit = 0;
for (int i=0;i<gAdditionalGlobalStats.numStats;i++) {
if ((gAdditionalGlobalStats.stats[i].source == source) && (gAdditionalGlobalStats.stats[i].name == name)) {
foundit = 1;
break;
}
}
if (!foundit) {
gAdditionalGlobalStats.stats[gAdditionalGlobalStats.numStats].source = source;
gAdditionalGlobalStats.stats[gAdditionalGlobalStats.numStats].name = name;
gAdditionalGlobalStats.numStats++;
}
g_mainDialog->UpdateStatsLists();
}
void ClearTitleAdditionalGlobalStats(CString source, CString name) {
int foundit = 0;
int i,j;
for (i=0;i<gAdditionalGlobalStats.numStats;i++) {
gAdditionalGlobalStats.stats[i].titleFlag = 0;
}
for (i=0;i<numMainStats;i++) {
for (j=0;j<gStats[i].numStats;j++) {
if ((gStats[i].source == source) && (gStats[i].stats[j].name == name)) {
gStats[i].stats[j].titleFlag = 0;
}
}
}
g_mainDialog->UpdateStatsLists();
}
void AddToTitleAdditionalGlobalStats(CString source, CString name) {
int foundit = 0;
int i,j;
for (i=0;i<gAdditionalGlobalStats.numStats;i++) {
if ((gAdditionalGlobalStats.stats[i].source == source) && (gAdditionalGlobalStats.stats[i].name == name)) {
ClearTitleAdditionalGlobalStats(source, name);
gAdditionalGlobalStats.stats[i].titleFlag = 1;
strcpy(gTitleSource, source);
strcpy(gTitleName, name);
foundit = 1;
break;
}
}
if (!foundit) {
for (i=0;i<numMainStats;i++) {
for (j=0;j<gStats[i].numStats;j++) {
if ((gStats[i].source == source) && (gStats[i].stats[j].name == name)) {
ClearTitleAdditionalGlobalStats(source, name);
gStats[i].stats[j].titleFlag = 1;
strcpy(gTitleSource, source);
strcpy(gTitleName, name);
foundit = 1;
break;
}
}
}
}
g_mainDialog->UpdateStatsLists();
}
void RemoveFromAdditionalGlobalStats(CString source, CString name) {
int foundit = 0;
for (int i=0;i<gAdditionalGlobalStats.numStats;i++) {
if ((gAdditionalGlobalStats.stats[i].source == source) && (gAdditionalGlobalStats.stats[i].name == name)) {
for (int j=i+1;j < gAdditionalGlobalStats.numStats;j++) {
gAdditionalGlobalStats.stats[j-1].name = gAdditionalGlobalStats.stats[j].name;
gAdditionalGlobalStats.stats[j-1].value = gAdditionalGlobalStats.stats[j].value;
gAdditionalGlobalStats.stats[j-1].source = gAdditionalGlobalStats.stats[j].source;
}
gAdditionalGlobalStats.numStats--;
break;
}
}
g_mainDialog->UpdateStatsLists();
}
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIcecast2winDlg dialog
CIcecast2winDlg::CIcecast2winDlg(CWnd* pParent /*=NULL*/)
: CDialog(CIcecast2winDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CIcecast2winDlg)
m_AccessEdit = _T("");
m_ErrorEdit = _T("");
m_ConfigEdit = _T("");
m_ServerStatus = _T("");
m_SourcesConnected = _T("");
m_NumClients = _T("");
m_StatsEdit = _T("");
m_Autostart = FALSE;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pTray = NULL;
}
void CIcecast2winDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CIcecast2winDlg)
DDX_Control(pDX, IDC_STATIC_SS, m_SS);
DDX_Control(pDX, IDC_SERVERSTATUS, m_ServerStatusBitmap);
DDX_Control(pDX, IDC_START, m_StartButton);
DDX_Control(pDX, IDC_MAINTAB, m_MainTab);
DDX_Check(pDX, IDC_AUTOSTART, m_Autostart);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CIcecast2winDlg, CDialog)
//{{AFX_MSG_MAP(CIcecast2winDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_NOTIFY(TCN_SELCHANGE, IDC_MAINTAB, OnSelchangeMaintab)
ON_COMMAND(ID_FILE_EXIT, OnFileExit)
ON_WM_TIMER()
ON_COMMAND(ID_FILE_STARTSERVER, OnFileStartserver)
ON_COMMAND(ID_FILE_STOPSERVER, OnFileStopserver)
ON_BN_CLICKED(IDC_START, OnStart)
ON_WM_CLOSE()
ON_WM_SIZE()
ON_BN_CLICKED(IDC_HIDESYSTRAY, OnHidesystray)
ON_COMMAND(ID_BLANK_RESTORE, OnBlankRestore)
ON_MESSAGE(WM_TRAY_NOTIFY, OnTrayNotify)
ON_WM_DESTROY()
ON_COMMAND(ID_FILE_EDITCONFIGURATION, OnFileEditconfiguration)
ON_COMMAND(ID_ABOUT_HELP, OnAboutHelp)
ON_COMMAND(ID_ABOUT_CREDITS, OnAboutCredits)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIcecast2winDlg message handlers
#include "colors.h"
BOOL CIcecast2winDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
g_mainDialog = this;
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
config_read();
statsTab.m_colSource0Width = m_colSource0Width;
statsTab.m_colStats0Width = m_colStats0Width;
statsTab.m_colStats1Width = m_colStats1Width;
statusTab.m_colStats0Width = m_colGStats0Width;
statusTab.m_colStats1Width = m_colGStats1Width;
statusTab.m_colStats2Width = m_colGStats2Width;
statsTab.Create(IDD_STATSDIALOG, this);
statusTab.Create(IDD_SSTATUS, this);
int nPageID = 0;
m_MainTab.AddSSLPage (_T("Server Status"), nPageID, (CTabPageSSL *)&statusTab);
nPageID++;
m_MainTab.AddSSLPage (_T("Source Level Stats"), nPageID, (CTabPageSSL *)&statsTab);
nPageID++;
labelFont.CreateFont(24,0, 0, 0, FW_BOLD, 0, 0, 0, 0, OUT_TT_PRECIS, 0, PROOF_QUALITY, 0, "Arial");
runningBitmap.LoadBitmap(IDB_BITMAP6);
stoppedBitmap.LoadBitmap(IDB_BITMAP5);
UpdateData(FALSE);
LoadConfig();
// AddAnchor(IDC_MAINTAB, TOP_LEFT, BOTTOM_RIGHT);
// AddAnchor(IDC_STATICBLACK, TOP_LEFT, TOP_RIGHT);
// EnableSaveRestore("icecast2win", "positions");
m_pTray = NULL;
char version[255] = "";
sprintf(version, "Icecast2 Version %s", ICECAST_VERSION);
SetWindowText(version);
xslt_initialize();
curl_global_init (CURL_GLOBAL_ALL);
if (m_Autostart) {
OnStart();
}
return TRUE; // return TRUE unless you set the focus to a control
}
void CIcecast2winDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CIcecast2winDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CIcecast2winDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CIcecast2winDlg::OnSelchangeMaintab(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
*pResult = 0;
}
void CIcecast2winDlg::LoadConfig()
{
FILE *filep;
char buffer[2046] = "";
CIcecast2winApp *myApp = (CIcecast2winApp *)AfxGetApp();
configTab.m_Config = "";
filep = fopen(myApp->m_configFile, "r");
if (filep) {
fclose(filep);
}
else {
MessageBox("Unable to load config file (" + CString(myApp->m_configFile) + ") unable to start", NULL, MB_OK);
}
}
void CIcecast2winDlg::OnFileExit()
{
// TODO: Add your command handler code here
DestroyWindow();
}
void CIcecast2winDlg::getTag(char *pbuf, char *ptag, char *dest)
{
char openTag[256] = "";
char closeTag[256] = "";
sprintf(openTag, "<%s>", ptag);
sprintf(closeTag, "</%s>", ptag);
char *p1;
p1 = strstr(pbuf, openTag);
if (p1) {
p1 = p1 + strlen(openTag);
char *p2;
p2 = strstr(p1, closeTag);
if (p2) {
strncpy(dest, p1, p2-p1);
}
}
}
void CIcecast2winDlg::EnableControl(UINT control)
{
CWnd *pWnd;
pWnd = GetDlgItem(control);
::ShowWindow(pWnd->GetSafeHwnd(), SW_SHOW);
}
void CIcecast2winDlg::DisableControl(UINT control)
{
CWnd *pWnd;
pWnd = GetDlgItem(control);
::ShowWindow(pWnd->GetSafeHwnd(), SW_HIDE);
}
void AddUpdateStatistic(int sourceIndex, char *name, char *value)
{
for (int j=0;j<gStats[sourceIndex].numStats;j++) {
if (gStats[sourceIndex].stats[j].name == name) {
gStats[sourceIndex].stats[j].value = value;
return;
}
}
int numStats = gStats[sourceIndex].numStats;
if (numStats >= MAXSTATSPERSOURCE)
return;
/* If we get here, we haven't found the stat, so add it */
gStats[sourceIndex].stats[numStats].name = name;
gStats[sourceIndex].stats[numStats].value = value;
gStats[sourceIndex].numStats++;
}
int GetSourceIndex(char *sourceName)
{
if (sourceName == NULL) {
return 0;
}
for (int i=1;i<numMainStats+1;i++) {
if (!strcmp(gStats[i].source, sourceName)) {
return i;
}
}
if (numMainStats >= MAXSOURCES)
return 0;
/* This means we haven't seen the source, so lets add it */
numMainStats++;
gStats[numMainStats].source = sourceName;
gStats[numMainStats].populated = 1;
gStats[numMainStats].numStats = 0;
return numMainStats;
}
void UpdateSourceData(xmlDocPtr doc, xmlNodePtr cur, char *sourceName) {
xmlNodePtr children;
char *ls_xmlContentPtr = NULL;
int sourceIndex = GetSourceIndex(sourceName);
int listenerInd = 0;
children = cur->xmlChildrenNode;
while (children != NULL) {
if (!strcmp((char *)children->name, "listeners")) {
listenerInd = 1;
}
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, children->xmlChildrenNode, 1);
AddUpdateStatistic(sourceIndex, (char *)children->name, ls_xmlContentPtr);
xmlFree(ls_xmlContentPtr);
children = children->next;
}
if (!listenerInd) {
/* If no listeners, then the source has been disconnected */
gStats[sourceIndex].populated = 0;
gStats[sourceIndex].numStats = 0;
g_mainDialog->statsTab.m_SourceListCtrl.DeleteAllItems();
g_mainDialog->statsTab.m_StatsListCtrl.DeleteAllItems();
}
}
bool g_collectingStats = false;
void StartStats(void *dummy)
{
while (global.running != ICE_RUNNING) {
Sleep(500);
}
while (global.running == ICE_RUNNING) {
if (global.running == ICE_RUNNING) {
for (int j=0;j<MAXSOURCES;j++) {
gStats[j].numStats = 0;
}
numMainStats = 0;
xmlDocPtr doc;
stats_get_xml(&doc, 0, NULL);
xmlNodePtr cur;
cur = xmlDocGetRootElement(doc);
if (cur == NULL) {
MessageBox(NULL, "empty XML document", "Error", MB_OK);
xmlFreeDoc(doc);
return;
}
cur = cur->xmlChildrenNode;
char* ls_xmlContentPtr2 = NULL;
while (cur != NULL) {
if ((!xmlStrcmp(cur->name, (const xmlChar *)"source"))) {
ls_xmlContentPtr2 = (char *)xmlGetProp(cur, (unsigned char *)"mount");
UpdateSourceData(doc, cur, ls_xmlContentPtr2);
}
else {
/* A Global stat */
ls_xmlContentPtr2 = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
AddUpdateStatistic(0, (char *)cur->name, ls_xmlContentPtr2);
}
if (ls_xmlContentPtr2) {
xmlFree(ls_xmlContentPtr2);
}
cur = cur->next;
}
xmlFreeDoc(doc);
g_mainDialog->UpdateStatsLists();
Sleep(5000);
}
if (global.running != ICE_RUNNING) {
numMainStats = 0;
g_mainDialog->statusTab.m_GlobalStatList.DeleteAllItems();
g_mainDialog->statsTab.m_SourceListCtrl.DeleteAllItems();
g_mainDialog->statsTab.m_StatsListCtrl.DeleteAllItems();
_endthread();
}
}
_endthread();
}
void CIcecast2winDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if (nIDEvent == 0) {
if (global.running == ICE_RUNNING) {
char buffer[255] = "";
CString tmp;
// Get info from stats...
m_ServerStatusBitmap.SetBitmap(HBITMAP(runningBitmap));
sprintf(buffer, "%d", global.sources);
tmp = buffer;
if (tmp != statusTab.m_Sources) {
statusTab.m_Sources = tmp;
statusTab.UpdateData(FALSE);
}
sprintf(buffer, "%d", global.clients);
tmp = buffer;
if (tmp != statusTab.m_Clients) {
statusTab.m_Clients = tmp;
statusTab.UpdateData(FALSE);
}
m_StartButton.GetWindowText(tmp);
if (tmp == "Start Server") {
m_StartButton.SetWindowText("Stop Server");
m_StartButton.SetState(0);
}
time_t currentTime;
time(&currentTime);
time_t runningTime = currentTime - serverStart;
CTimeSpan runningFor(runningTime);
char timespan[1024] = "";
sprintf(timespan, "%d Days, %d Hours, %d Minutes, %d Seconds", runningFor.GetDays(), runningFor.GetHours(), runningFor.GetMinutes(), runningFor.GetSeconds());
statusTab.m_RunningFor = timespan;
statusTab.UpdateData(FALSE);
SetTimer(0, 500, NULL);
}
else {
statusTab.m_Sources = "0";
statusTab.m_Clients = "0";
m_ServerStatusBitmap.SetBitmap(HBITMAP(stoppedBitmap));
m_StartButton.SetWindowText("Start Server");
m_StartButton.SetState(0);
UpdateData(FALSE);
statusTab.m_RunningFor = "Not running";
statusTab.UpdateData(FALSE);
}
}
CDialog::OnTimer(nIDEvent);
}
char g_configFile[1024] = "";
char g_progName[255] = "icecast2";
void StartServer(void *configfile)
{
int argc = 3;
char* argv[3];
strcpy(g_configFile, (char *)configfile);
argv[0] = g_progName;
argv[1] = "-c";
argv[2] = g_configFile;
time(&(g_mainDialog->serverStart));
int ret = main(argc, (char **)argv);
if (ret) {
MessageBox(NULL, "Unable to start server", NULL, MB_OK);
}
global.running = ICE_HALTING;
_endthread();
}
void CIcecast2winDlg::OnFileStartserver()
{
// TODO: Add your command handler code here
CIcecast2winApp *myApp = (CIcecast2winApp *)AfxGetApp();
if (gConfigurationSave == "") {
gConfigurationSave = m_ConfigEdit;
}
if (global.running == ICE_RUNNING) {
MessageBox("Server already running", "Error", MB_OK);
}
else {
m_ConfigEditCtrl.SetReadOnly(TRUE);
LoadConfig();
SetTimer(0, 500, NULL);
_beginthread(StartServer, 0, (void *)(LPCSTR)myApp->m_configFile);
_beginthread(StartStats, 0, (void *)NULL);
}
}
void CIcecast2winDlg::OnFileStopserver()
{
// TODO: Add your command handler code here
;
}
bool infocus = false;
void CIcecast2winDlg::StopServer()
{
KillTimer(0);
global.running = ICE_HALTING;
m_StartButton.SetWindowText("Start Server");
m_StartButton.SetState(0);
m_ServerStatusBitmap.SetBitmap(HBITMAP(stoppedBitmap));
statusTab.m_RunningFor = "Not running";
statusTab.UpdateData(FALSE);
}
void CIcecast2winDlg::OnStart()
{
CIcecast2winApp *myApp = (CIcecast2winApp *)AfxGetApp();
// TODO: Add your control notification handler code here
if (global.running == ICE_RUNNING) {
StopServer();
}
else {
SetTimer(0, 500, NULL);
_beginthread(StartServer, 0, (void *)(LPCSTR)myApp->m_configFile);
_beginthread(StartStats, 0, (void *)NULL);
}
}
void CIcecast2winDlg::UpdateStatsLists()
{
char item[1024] = "";
int l = 0;
// Global Stats are index of 0
for (int k=0;k < gStats[0].numStats;k++) {
int inthere = 0;
for (l=0;l < statusTab.m_GlobalStatList.GetItemCount();l++) {
statusTab.m_GlobalStatList.GetItemText(l, 1, item, sizeof(item));
if (!strcmp(gStats[0].stats[k].name, item)) {
inthere = 1;
break;
}
}
if (!inthere) {
LVITEM lvi;
lvi.mask = LVIF_IMAGE | LVIF_TEXT;
lvi.iItem = statsTab.m_SourceListCtrl.GetItemCount();
lvi.iSubItem = 0;
//lvi.pszText = (LPTSTR)(LPCTSTR)gStats[0].source;
lvi.pszText = "Global Stat";
statusTab.m_GlobalStatList.InsertItem(&lvi);
lvi.iSubItem = 1;
lvi.pszText = (LPTSTR)(LPCTSTR)gStats[0].stats[k].name;
statusTab.m_GlobalStatList.SetItem(&lvi);
lvi.iSubItem = 2;
lvi.pszText = (LPTSTR)(LPCTSTR)gStats[0].stats[k].value;
statusTab.m_GlobalStatList.SetItem(&lvi);
if ((!strcmp(gTitleSource, gStats[0].source)) &&
(!strcmp(gTitleName, gStats[0].stats[k].name))) {
gStats[0].stats[k].titleFlag = 1;
}
}
else {
LVITEM lvi;
lvi.mask = LVIF_IMAGE | LVIF_TEXT;
lvi.iItem = l;
lvi.iSubItem = 2;
lvi.pszText = (LPTSTR)(LPCTSTR)gStats[0].stats[k].value;
statusTab.m_GlobalStatList.SetItem(&lvi);
}
if (gStats[0].stats[k].titleFlag) {
CString windowTitle = CString("Global Stat") + " - " + gStats[0].stats[k].name + " - " + gStats[0].stats[k].value;
SetWindowText(windowTitle);
if (m_pTray) {
m_pTray->SetTIP((LPSTR)(LPCSTR)windowTitle);
}
}
}
for (int i=1;i<numMainStats+1;i++) {
int inthere = 0;
int k = 0;
if (gStats[i].populated) {
for (l=0;l < gAdditionalGlobalStats.numStats;l++) {
for (int m=0;m < gStats[i].numStats;m++) {
if ((gAdditionalGlobalStats.stats[l].source == gStats[i].source) &&
(gAdditionalGlobalStats.stats[l].name == gStats[i].stats[m].name)) {
gAdditionalGlobalStats.stats[l].value = gStats[i].stats[m].value;
break;
}
}
}
if (strcmp(gStats[i].source, "Global Stat")) {
// If Not Global STat
for (k=0;k < statsTab.m_SourceListCtrl.GetItemCount();k++) {
statsTab.m_SourceListCtrl.GetItemText(k, 0, item, sizeof(item));
if (!strcmp(gStats[i].source, item)) {
inthere = 1;
break;
}
}
if (!inthere) {
if (gStats[i].source != "") {
LVITEM lvi;
lvi.mask = LVIF_IMAGE | LVIF_TEXT;
lvi.iItem = statsTab.m_SourceListCtrl.GetItemCount();
lvi.iSubItem = 0;
lvi.pszText = (LPTSTR)(LPCTSTR)gStats[i].source;
statsTab.m_SourceListCtrl.InsertItem(&lvi);
}
}
int nItemSelected = statsTab.m_SourceListCtrl.GetSelectionMark();
if (nItemSelected != -1) {
memset(item, '\000', sizeof(item));
statsTab.m_SourceListCtrl.GetItemText(nItemSelected, 0, item, sizeof(item));
if (!strcmp(gStats[i].source, item)) {
for (int l=0;l<gStats[i].numStats;l++) {
int inthere2 = 0;
char item2[1024] = "";
for (int m=0;m < statsTab.m_StatsListCtrl.GetItemCount();m++) {
statsTab.m_StatsListCtrl.GetItemText(m, 0, item2, sizeof(item2));
if (!strcmp(gStats[i].stats[l].name, item2)) {
LVITEM lvi;
lvi.mask = LVIF_TEXT;
lvi.iItem = m;
lvi.iSubItem = 1;
lvi.pszText = (LPTSTR)(LPCTSTR)gStats[i].stats[l].value;
statsTab.m_StatsListCtrl.SetItem(&lvi);
inthere2 = 1;
break;
}
}
if (!inthere2) {
LVITEM lvi;
lvi.mask = LVIF_TEXT;
lvi.iItem = statsTab.m_StatsListCtrl.GetItemCount();
lvi.iSubItem = 0;
lvi.pszText = (LPTSTR)(LPCTSTR)gStats[i].stats[l].name;
statsTab.m_StatsListCtrl.InsertItem(&lvi);
lvi.iSubItem = 1;
lvi.pszText = (LPTSTR)(LPCTSTR)gStats[i].stats[l].value;
statsTab.m_StatsListCtrl.SetItem(&lvi);
}
}
}
}
for (l=0;l < gAdditionalGlobalStats.numStats;l++) {
int inthere2 = 0;
char item2[1024] = "";
char item3[1024] = "";
CString itemSource;
CString itemName;
for (int m=0;m < statusTab.m_GlobalStatList.GetItemCount();m++) {
statusTab.m_GlobalStatList.GetItemText(m, 0, item2, sizeof(item2));
statusTab.m_GlobalStatList.GetItemText(m, 1, item3, sizeof(item3));
itemSource = item2;
itemName = item3;
if ((gAdditionalGlobalStats.stats[l].source == itemSource) &&
(gAdditionalGlobalStats.stats[l].name == itemName)) {
LVITEM lvi;
lvi.mask = LVIF_TEXT;
lvi.iItem = m;
lvi.iSubItem = 2;
lvi.pszText = (LPTSTR)(LPCTSTR)gAdditionalGlobalStats.stats[l].value;
statusTab.m_GlobalStatList.SetItem(&lvi);
inthere2 = 1;
break;
}
}
if (!inthere2) {
LVITEM lvi;
lvi.mask = LVIF_TEXT;
lvi.iItem = statusTab.m_GlobalStatList.GetItemCount();
lvi.iSubItem = 0;
lvi.pszText = (LPTSTR)(LPCTSTR)gAdditionalGlobalStats.stats[l].source;
statusTab.m_GlobalStatList.InsertItem(&lvi);
lvi.iSubItem = 1;
lvi.pszText = (LPTSTR)(LPCTSTR)gAdditionalGlobalStats.stats[l].name;
statusTab.m_GlobalStatList.SetItem(&lvi);
lvi.iSubItem = 2;
lvi.pszText = (LPTSTR)(LPCTSTR)gAdditionalGlobalStats.stats[l].value;
statusTab.m_GlobalStatList.SetItem(&lvi);
if ((!strcmp(gTitleSource, gAdditionalGlobalStats.stats[l].source)) &&
(!strcmp(gTitleName, gAdditionalGlobalStats.stats[l].name))) {
gAdditionalGlobalStats.stats[l].titleFlag = 1;
}
}
if (gAdditionalGlobalStats.stats[l].titleFlag) {
CString windowTitle = gAdditionalGlobalStats.stats[l].source + " - " + gAdditionalGlobalStats.stats[l].name + " - " + gAdditionalGlobalStats.stats[l].value;
SetWindowText(windowTitle);
if (m_pTray) {
m_pTray->SetTIP((LPSTR)(LPCSTR)windowTitle);
}
}
}
}
else {
}
}
}
}
char gAppName[255] = "icecast2";
char gConfigFile[255] = "icecast2.ini";
void CIcecast2winDlg::config_write()
{
char buf[255] = "";
char buf2[1024] = "";
UpdateData(TRUE);
m_colSource0Width = statsTab.m_SourceListCtrl.GetColumnWidth(0);
m_colStats0Width = statsTab.m_StatsListCtrl.GetColumnWidth(0);
m_colStats1Width = statsTab.m_StatsListCtrl.GetColumnWidth(1);
m_colGStats0Width = statusTab.m_GlobalStatList.GetColumnWidth(0);
m_colGStats1Width = statusTab.m_GlobalStatList.GetColumnWidth(1);
m_colGStats2Width = statusTab.m_GlobalStatList.GetColumnWidth(2);
sprintf(buf, "%d", m_colSource0Width);
WritePrivateProfileString(gAppName, "col0SourceWidth", buf, gConfigFile);
sprintf(buf, "%d", m_colStats0Width);
WritePrivateProfileString(gAppName, "col0StatsWidth", buf, gConfigFile);
sprintf(buf, "%d", m_colStats1Width);
WritePrivateProfileString(gAppName, "col1StatsWidth", buf, gConfigFile);
sprintf(buf, "%d", m_colGStats0Width);
WritePrivateProfileString(gAppName, "col0GStatsWidth", buf, gConfigFile);
sprintf(buf, "%d", m_colGStats1Width);
WritePrivateProfileString(gAppName, "col1GStatsWidth", buf, gConfigFile);
sprintf(buf, "%d", m_colGStats2Width);
WritePrivateProfileString(gAppName, "col2GStatsWidth", buf, gConfigFile);
if (m_Autostart) {
WritePrivateProfileString(gAppName, "AutoStart", "1", gConfigFile);
}
else {
WritePrivateProfileString(gAppName, "AutoStart", "0", gConfigFile);
}
sprintf(buf, "%d", gAdditionalGlobalStats.numStats);
WritePrivateProfileString(gAppName, "numAdditionalStats", buf, gConfigFile);
for (int i=0;i<gAdditionalGlobalStats.numStats;i++) {
memset(buf, '\000', sizeof(buf));
sprintf(buf2, "AdditionalStatsSource%d", i);
WritePrivateProfileString(gAppName, buf2, gAdditionalGlobalStats.stats[i].source, gConfigFile);
memset(buf, '\000', sizeof(buf));
sprintf(buf2, "AdditionalStatsName%d", i);
WritePrivateProfileString(gAppName, buf2, gAdditionalGlobalStats.stats[i].name, gConfigFile);
if (gAdditionalGlobalStats.stats[i].titleFlag) {
sprintf(buf2, "%s|%s", gAdditionalGlobalStats.stats[i].source, gAdditionalGlobalStats.stats[i].name);
WritePrivateProfileString(gAppName, "TitleName", buf2, gConfigFile);
}
}
for (i=0;i<numMainStats;i++) {
for (int k=0;k < gStats[i].numStats;k++) {
if (gStats[i].stats[k].titleFlag) {
sprintf(buf2, "%s|%s", gStats[i].source, gStats[i].stats[k].name);
WritePrivateProfileString(gAppName, "TitleName", buf2, gConfigFile);
}
}
}
}
void CIcecast2winDlg::config_read()
{
char buf2[1024] = "";
char buf[1024] = "";
CString tempString;
m_colSource0Width = GetPrivateProfileInt(gAppName, "col0SourceWidth", 163, gConfigFile);
m_colStats0Width = GetPrivateProfileInt(gAppName, "col0StatsWidth", 100, gConfigFile);
m_colStats1Width = GetPrivateProfileInt(gAppName, "col1StatsWidth", 150, gConfigFile);
m_colGStats0Width = GetPrivateProfileInt(gAppName, "col0GStatsWidth", 150, gConfigFile);
m_colGStats1Width = GetPrivateProfileInt(gAppName, "col1GStatsWidth", 150, gConfigFile);
m_colGStats2Width = GetPrivateProfileInt(gAppName, "col2GStatsWidth", 150, gConfigFile);
GetPrivateProfileString(gAppName, "AutoStart", "0", buf, sizeof(buf), gConfigFile);
if (!strcmp(buf, "1")) {
m_Autostart = true;
}
else{
m_Autostart = false;
}
int numAdditionalGlobalStats = GetPrivateProfileInt(gAppName, "numAdditionalStats", 0, gConfigFile);
for (int i=0;i<numAdditionalGlobalStats;i++) {
memset(buf, '\000', sizeof(buf));
sprintf(buf2, "AdditionalStatsSource%d", i);
GetPrivateProfileString(gAppName, buf2, "", buf, sizeof(buf), gConfigFile);
gAdditionalGlobalStats.stats[i].source = buf;
memset(buf, '\000', sizeof(buf));
sprintf(buf2, "AdditionalStatsName%d", i);
GetPrivateProfileString(gAppName, buf2, "", buf, sizeof(buf), gConfigFile);
gAdditionalGlobalStats.stats[i].name = buf;
gAdditionalGlobalStats.numStats++;
}
GetPrivateProfileString(gAppName, "TitleName", "", buf, sizeof(buf), gConfigFile);
if (strlen(buf) > 0) {
char *p1 = strchr(buf, '|');
if (p1) {
char tmpSource[1024] = "";
char tmpName[1024] = "";
memset(tmpSource, '\000', sizeof(tmpSource));
memset(tmpName, '\000', sizeof(tmpName));
strncpy(tmpSource, buf, p1-buf);
p1++;
strcpy(tmpName, p1);
strcpy(gTitleSource, tmpSource);
strcpy(gTitleName, tmpName);
}
}
}
void CIcecast2winDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
config_write();
CDialog::OnClose();
}
void CIcecast2winDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
int border1 = 0;
int border2 = 78;
// TODO: Add your message handler code here
if (m_MainTab.m_hWnd) {
CRect rect;
GetClientRect (&rect);
int x = rect.Width()-border1;
int y = rect.Width()-border2;
statusTab.SetWindowPos(NULL, 4, 22, cx, cy, SWP_NOZORDER);
statsTab.SetWindowPos(NULL, 4, 22, cx, cy, SWP_NOZORDER);
statusTab.m_GlobalStatList.SetWindowPos(NULL, 14, 55, cx-40, cy-180, SWP_NOZORDER);
statsTab.m_StatsListCtrl.SetWindowPos(NULL, 213, 55, cx-243, cy-180, SWP_NOZORDER);
statsTab.m_SourceListCtrl.SetWindowPos(NULL, 14, 55, 166, cy-180, SWP_NOZORDER);
// CListCtrl m_StatsListCtrl;
// CListCtrl m_SourceListCtrl;
m_MainTab.SetWindowPos(NULL, 0, 80, cx, cy, SWP_NOZORDER);
//m_MainTab.ResizeDialog(0, rect.Width()-border1, rect.Height()-border2);
//m_MainTab.ResizeDialog(1, rect.Width()-border1, rect.Height()-border2);
}
}
LONG CIcecast2winDlg::OnTrayNotify ( WPARAM wParam, LPARAM lParam )
{
switch (lParam) {
case WM_RBUTTONDOWN:
{
CMenu menu ;
// Load and Verify Menu
VERIFY(menu.LoadMenu(IDR_TRAY));
CMenu* pPopup = menu.GetSubMenu (0) ;
ASSERT(pPopup != NULL);
// Get the cursor position
POINT pt ;
GetCursorPos (&pt) ;
// Fix Microsofts' BUG!!!!
SetForegroundWindow();
///////////////////////////////////
// Display The Menu
pPopup->TrackPopupMenu(TPM_LEFTALIGN |
TPM_RIGHTBUTTON,pt.x, pt.y, AfxGetMainWnd());
break ;
}
case WM_LBUTTONDBLCLK:
//////////////////////////////////
// Unhide our Window
if (m_bHidden) {
ShowWindow (SW_RESTORE);
}
//OnUnHide() ;
break ;
}
return (0) ;
}
void CIcecast2winDlg::OnHidesystray()
{
// TODO: Add your control notification handler code here
OnHide();
theApp.HideApplication();
}
void CIcecast2winDlg::OnHide()
{
// TODO: Add your control notification handler code here
if (m_pTray == NULL) {
m_pTray = new CTrayNot (this,WM_TRAY_NOTIFY, NULL,theApp.m_pIconList);
}
m_pTray->SetState(0);
m_bHidden = TRUE;
}
void CIcecast2winDlg::OnBlankRestore()
{
// TODO: Add your command handler code here
if (m_bHidden) {
ShowWindow (SW_RESTORE);
}
}
void CIcecast2winDlg::OnDestroy()
{
CDialog::OnDestroy();
if (m_pTray) {
delete m_pTray ;
m_pTray = NULL ;
}
// TODO: Add your message handler code here
}
void CIcecast2winDlg::OnFileEditconfiguration()
{
// TODO: Add your command handler code here
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
int ok = 1;
if (global.running == ICE_RUNNING) {
MessageBox("I'm sorry, but you cannot edit the configuration file while the server is running", NULL, MB_OK);
}
else {
// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line).
"notepad icecast.xml", // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
ok = 0;
}
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
}
void CIcecast2winDlg::OnAboutHelp()
{
// TODO: Add your command handler code here
ShellExecute(NULL, "open", "doc\\icecast2.chm", NULL, NULL, SW_SHOWNORMAL);
}
void CIcecast2winDlg::OnAboutCredits()
{
// TODO: Add your command handler code here
CAboutDlg about;
about.DoModal();
}