diff --git a/LameXP.vcproj b/LameXP.vcproj
index 2fab5ce8..7763dca8 100644
--- a/LameXP.vcproj
+++ b/LameXP.vcproj
@@ -207,6 +207,10 @@
RelativePath=".\src\Dialog_WorkingBanner.cpp"
>
+
+
@@ -239,6 +243,10 @@
RelativePath=".\src\Thread_Initialization.cpp"
>
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Dialog_MainWindow.cpp b/src/Dialog_MainWindow.cpp
index 93f1ea83..6330231a 100644
--- a/src/Dialog_MainWindow.cpp
+++ b/src/Dialog_MainWindow.cpp
@@ -27,6 +27,7 @@
#include "Dialog_WorkingBanner.h"
#include "Dialog_MetaInfo.h"
#include "Thread_FileAnalyzer.h"
+#include "Thread_MessageHandler.h"
//Qt includes
#include
@@ -140,6 +141,10 @@ MainWindow::MainWindow(QWidget *parent)
//Create banner
m_banner = new WorkingBanner(this);
+
+ //Create message handler thread
+ m_messageHandler = new MessageHandlerThread();
+ m_messageHandler->start();
}
////////////////////////////////////////////////////////////
@@ -161,10 +166,59 @@ MainWindow::~MainWindow(void)
/*NONE*/
+////////////////////////////////////////////////////////////
+// EVENTS
+////////////////////////////////////////////////////////////
+
+void MainWindow::showEvent(QShowEvent *event)
+{
+ QTimer::singleShot(0, this, SLOT(windowShown()));
+}
+
////////////////////////////////////////////////////////////
// Slots
////////////////////////////////////////////////////////////
+/*
+ * Window shown
+ */
+void MainWindow::windowShown(void)
+{
+ QStringList fileList;
+ QStringList arguments = QApplication::arguments();
+ qDebug("Main window is showing");
+
+ for(int i = 0; i < arguments.count() - 1; i++)
+ {
+ if(!arguments[i].compare("--add", Qt::CaseInsensitive))
+ {
+ QFileInfo currentFile(arguments[++i].trimmed());
+ qDebug("Adding file from CLI: %s", currentFile.absoluteFilePath().toUtf8().constData());
+ if(currentFile.exists())
+ {
+ fileList << currentFile.absoluteFilePath();
+ }
+ else
+ {
+ qWarning("File doesn't exist: %s", currentFile.absoluteFilePath().toUtf8().constData());
+ }
+ }
+ }
+
+ if(fileList.count() > 0)
+ {
+ FileAnalyzer *analyzer = new FileAnalyzer(fileList);
+ connect(analyzer, SIGNAL(fileSelected(QString)), m_banner, SLOT(setText(QString)), Qt::QueuedConnection);
+ connect(analyzer, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection);
+
+ m_banner->show("Adding file(s), please wait...", analyzer);
+ LAMEXP_DELETE(analyzer);
+
+ sourceFileView->scrollToBottom();
+ m_banner->close();
+ }
+}
+
/*
* About button
*/
diff --git a/src/Dialog_MainWindow.h b/src/Dialog_MainWindow.h
index 38fee2dd..aaec4e40 100644
--- a/src/Dialog_MainWindow.h
+++ b/src/Dialog_MainWindow.h
@@ -28,6 +28,7 @@
//Class declarations
class QFileSystemModel;
class WorkingBanner;
+class MessageHandlerThread;
class MainWindow: public QMainWindow, private Ui::MainWindow
{
@@ -38,6 +39,7 @@ public:
~MainWindow(void);
private slots:
+ void windowShown(void);
void aboutButtonClicked(void);
void encodeButtonClicked(void);
void addFilesButtonClicked(void);
@@ -58,10 +60,14 @@ private slots:
void visitHomepageActionActivated(void);
void openFolderActionActivated(void);
+protected:
+ void showEvent(QShowEvent *event);
+
private:
FileListModel *m_fileListModel;
QFileSystemModel *m_fileSystemModel;
QActionGroup *m_tabActionGroup;
QActionGroup *m_styleActionGroup;
WorkingBanner *m_banner;
+ MessageHandlerThread *m_messageHandler;
};
diff --git a/src/Genres.cpp b/src/Genres.cpp
new file mode 100644
index 00000000..b94597cf
--- /dev/null
+++ b/src/Genres.cpp
@@ -0,0 +1,175 @@
+///////////////////////////////////////////////////////////////////////////////
+// LameXP - Audio Encoder Front-End
+// Copyright (C) 2004-2010 LoRd_MuldeR
+//
+// 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 option) 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.
+//
+// http://www.gnu.org/licenses/gpl-2.0.txt
+///////////////////////////////////////////////////////////////////////////////
+
+#include
+
+extern const char *g_lamexp_generes[] =
+{
+ "Blues",
+ "Classic Rock",
+ "Country",
+ "Dance",
+ "Disco",
+ "Funk",
+ "Grunge",
+ "Hip-Hop",
+ "Jazz",
+ "Metal",
+ "New Age",
+ "Oldies",
+ "Other",
+ "Pop",
+ "R&B",
+ "Rap",
+ "Reggae",
+ "Rock",
+ "Techno",
+ "Industrial",
+ "Alternative",
+ "Ska",
+ "Death Metal",
+ "Pranks",
+ "Soundtrack",
+ "Euro-Techno",
+ "Ambient",
+ "Trip-Hop",
+ "Vocal",
+ "Jazz+Funk",
+ "Fusion",
+ "Trance",
+ "Classical",
+ "Instrumental",
+ "Acid",
+ "House",
+ "Game",
+ "Sound Clip",
+ "Gospel",
+ "Noise",
+ "Alternative Rock",
+ "Bass",
+ "Soul",
+ "Punk",
+ "Space",
+ "Meditative",
+ "Instrumental Pop",
+ "Instrumental Rock",
+ "Ethnic",
+ "Gothic",
+ "Darkwave",
+ "Techno-Industrial",
+ "Electronic",
+ "Pop-Folk",
+ "Eurodance",
+ "Dream",
+ "Southern Rock",
+ "Comedy",
+ "Cult",
+ "Gangsta",
+ "Top 40",
+ "Christian Rap",
+ "Pop/Funk",
+ "Jungle",
+ "Native US",
+ "Cabaret",
+ "New Wave",
+ "Psychadelic",
+ "Rave",
+ "Showtunes",
+ "Trailer",
+ "Lo-Fi",
+ "Tribal",
+ "Acid Punk",
+ "Acid Jazz",
+ "Polka",
+ "Retro",
+ "Musical",
+ "Rock & Roll",
+ "Hard Rock",
+ "Folk",
+ "Folk-Rock",
+ "National Folk",
+ "Swing",
+ "Fast Fusion",
+ "Bebob",
+ "Latin",
+ "Revival",
+ "Celtic",
+ "Bluegrass",
+ "Avantgarde",
+ "Gothic Rock",
+ "Progressive Rock",
+ "Psychedelic Rock",
+ "Symphonic Rock",
+ "Slow Rock",
+ "Big Band",
+ "Chorus",
+ "Easy Listening",
+ "Acoustic",
+ "Humour",
+ "Speech",
+ "Chanson",
+ "Opera",
+ "Chamber Music",
+ "Sonata",
+ "Symphony",
+ "Booty Bass",
+ "Primus",
+ "Porn Groove",
+ "Satire",
+ "Slow Jam",
+ "Club",
+ "Tango",
+ "Samba",
+ "Folklore",
+ "Ballad",
+ "Power Ballad",
+ "Rhytmic Soul",
+ "Freestyle",
+ "Duet",
+ "Punk Rock",
+ "Drum Solo",
+ "Acapella",
+ "Euro-House",
+ "Dance Hall",
+ "Goa",
+ "Drum & Bass",
+ "Club-House",
+ "Hardcore",
+ "Terror",
+ "Indie",
+ "BritPop",
+ "Negerpunk",
+ "Polsk Punk",
+ "Beat",
+ "Christian Gangsta",
+ "Heavy Metal",
+ "Black Metal",
+ "Crossover",
+ "Contemporary C",
+ "Christian Rock",
+ "Merengue",
+ "Salsa",
+ "Thrash Metal",
+ "Anime",
+ "JPop",
+ "SynthPop",
+ NULL
+};
diff --git a/src/Genres.h b/src/Genres.h
index 6de306c0..97c073bc 100644
--- a/src/Genres.h
+++ b/src/Genres.h
@@ -19,155 +19,4 @@
// http://www.gnu.org/licenses/gpl-2.0.txt
///////////////////////////////////////////////////////////////////////////////
-const static char *g_lamexp_generes[] =
-{
- "Blues",
- "Classic Rock",
- "Country",
- "Dance",
- "Disco",
- "Funk",
- "Grunge",
- "Hip-Hop",
- "Jazz",
- "Metal",
- "New Age",
- "Oldies",
- "Other",
- "Pop",
- "R&B",
- "Rap",
- "Reggae",
- "Rock",
- "Techno",
- "Industrial",
- "Alternative",
- "Ska",
- "Death Metal",
- "Pranks",
- "Soundtrack",
- "Euro-Techno",
- "Ambient",
- "Trip-Hop",
- "Vocal",
- "Jazz+Funk",
- "Fusion",
- "Trance",
- "Classical",
- "Instrumental",
- "Acid",
- "House",
- "Game",
- "Sound Clip",
- "Gospel",
- "Noise",
- "Alternative Rock",
- "Bass",
- "Soul",
- "Punk",
- "Space",
- "Meditative",
- "Instrumental Pop",
- "Instrumental Rock",
- "Ethnic",
- "Gothic",
- "Darkwave",
- "Techno-Industrial",
- "Electronic",
- "Pop-Folk",
- "Eurodance",
- "Dream",
- "Southern Rock",
- "Comedy",
- "Cult",
- "Gangsta",
- "Top 40",
- "Christian Rap",
- "Pop/Funk",
- "Jungle",
- "Native US",
- "Cabaret",
- "New Wave",
- "Psychadelic",
- "Rave",
- "Showtunes",
- "Trailer",
- "Lo-Fi",
- "Tribal",
- "Acid Punk",
- "Acid Jazz",
- "Polka",
- "Retro",
- "Musical",
- "Rock & Roll",
- "Hard Rock",
- "Folk",
- "Folk-Rock",
- "National Folk",
- "Swing",
- "Fast Fusion",
- "Bebob",
- "Latin",
- "Revival",
- "Celtic",
- "Bluegrass",
- "Avantgarde",
- "Gothic Rock",
- "Progressive Rock",
- "Psychedelic Rock",
- "Symphonic Rock",
- "Slow Rock",
- "Big Band",
- "Chorus",
- "Easy Listening",
- "Acoustic",
- "Humour",
- "Speech",
- "Chanson",
- "Opera",
- "Chamber Music",
- "Sonata",
- "Symphony",
- "Booty Bass",
- "Primus",
- "Porn Groove",
- "Satire",
- "Slow Jam",
- "Club",
- "Tango",
- "Samba",
- "Folklore",
- "Ballad",
- "Power Ballad",
- "Rhytmic Soul",
- "Freestyle",
- "Duet",
- "Punk Rock",
- "Drum Solo",
- "Acapella",
- "Euro-House",
- "Dance Hall",
- "Goa",
- "Drum & Bass",
- "Club-House",
- "Hardcore",
- "Terror",
- "Indie",
- "BritPop",
- "Negerpunk",
- "Polsk Punk",
- "Beat",
- "Christian Gangsta",
- "Heavy Metal",
- "Black Metal",
- "Crossover",
- "Contemporary C",
- "Christian Rock",
- "Merengue",
- "Salsa",
- "Thrash Metal",
- "Anime",
- "JPop",
- "SynthPop",
- NULL
-};
+extern const char *g_lamexp_generes[];
diff --git a/src/Global.cpp b/src/Global.cpp
index a5dd8667..6e90f692 100644
--- a/src/Global.cpp
+++ b/src/Global.cpp
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
//LameXP includes
#include "Resource.h"
@@ -49,6 +50,18 @@
#include
#endif //_DEBUG
+///////////////////////////////////////////////////////////////////////////////
+// TYPES
+///////////////////////////////////////////////////////////////////////////////
+
+typedef struct
+{
+ unsigned int command;
+ unsigned int reserved_1;
+ unsigned int reserved_2;
+ char parameter[4096];
+} lamexp_ipc_t;
+
///////////////////////////////////////////////////////////////////////////////
// GLOBAL VARS
///////////////////////////////////////////////////////////////////////////////
@@ -73,6 +86,10 @@ static QMap g_lamexp_tool_registry;
//Shared memory
static const char *g_lamexp_sharedmem_uuid = "{21A68A42-6923-43bb-9CF6-64BF151942EE}";
static QSharedMemory *g_lamexp_sharedmem_ptr = NULL;
+static const char *g_lamexp_semaphore_read_uuid = "{7A605549-F58C-4d78-B4E5-06EFC34F405B}";
+static QSystemSemaphore *g_lamexp_semaphore_read_ptr = NULL;
+static const char *g_lamexp_semaphore_write_uuid = "{60AA8D04-F6B8-497d-81EB-0F600F4A65B5}";
+static QSystemSemaphore *g_lamexp_semaphore_write_ptr = NULL;
///////////////////////////////////////////////////////////////////////////////
// GLOBAL FUNCTIONS
@@ -245,35 +262,120 @@ bool lamexp_init_qt(int argc, char* argv[])
*/
bool lamexp_check_instances(void)
{
- if(g_lamexp_sharedmem_ptr)
+ if(g_lamexp_sharedmem_ptr && g_lamexp_semaphore_read_ptr && g_lamexp_semaphore_write_ptr)
{
return true;
}
- QSharedMemory *sharedMemory = new QSharedMemory(g_lamexp_sharedmem_uuid, NULL);
-
- if(!sharedMemory->create(1048576))
+ g_lamexp_semaphore_read_ptr = new QSystemSemaphore(g_lamexp_semaphore_read_uuid, 0);
+ g_lamexp_semaphore_write_ptr = new QSystemSemaphore(g_lamexp_semaphore_write_uuid, 0);
+
+ if(g_lamexp_semaphore_read_ptr->error() != QSystemSemaphore::NoError)
{
- if(sharedMemory->error() == QSharedMemory::AlreadyExists)
+ QString errorMessage = g_lamexp_semaphore_read_ptr->errorString();
+ LAMEXP_DELETE(g_lamexp_semaphore_read_ptr);
+ LAMEXP_DELETE(g_lamexp_semaphore_write_ptr);
+ qFatal("Failed to create system smaphore: %s", errorMessage.toUtf8().constData());
+ return false;
+ }
+ if(g_lamexp_semaphore_write_ptr->error() != QSystemSemaphore::NoError)
+ {
+ QString errorMessage = g_lamexp_semaphore_write_ptr->errorString();
+ LAMEXP_DELETE(g_lamexp_semaphore_read_ptr);
+ LAMEXP_DELETE(g_lamexp_semaphore_write_ptr);
+ qFatal("Failed to create system smaphore: %s", errorMessage.toUtf8().constData());
+ return false;
+ }
+
+ g_lamexp_sharedmem_ptr = new QSharedMemory(g_lamexp_sharedmem_uuid, NULL);
+
+ if(!g_lamexp_sharedmem_ptr->create(sizeof(lamexp_ipc_t)))
+ {
+ if(g_lamexp_sharedmem_ptr->error() == QSharedMemory::AlreadyExists)
{
- LAMEXP_DELETE(sharedMemory);
+ g_lamexp_sharedmem_ptr->attach();
+ if(g_lamexp_sharedmem_ptr->error() == QSharedMemory::NoError)
+ {
+ lamexp_ipc_send(42, "Wurst schmeckt uns!");
+ }
+ else
+ {
+ qWarning("Failed to attach to the existing shared memory!");
+ }
qWarning("Another instance of LameXP is already running on this computer!");
QMessageBox::warning(NULL, "LameXP", "LameXP is already running. Please use the running instance!");
- return false;
}
else
{
- QString errorMessage = sharedMemory->errorString();
- LAMEXP_DELETE(sharedMemory);
+ QString errorMessage = g_lamexp_sharedmem_ptr->errorString();
qFatal("Failed to create shared memory: %s", errorMessage.toUtf8().constData());
- return false;
}
+ LAMEXP_DELETE(g_lamexp_semaphore_read_ptr);
+ LAMEXP_DELETE(g_lamexp_semaphore_write_ptr);
+ LAMEXP_DELETE(g_lamexp_sharedmem_ptr);
+ return false;
}
- g_lamexp_sharedmem_ptr = sharedMemory;
+ memset(g_lamexp_sharedmem_ptr->data(), 0, sizeof(lamexp_ipc_t));
+ g_lamexp_semaphore_write_ptr->release();
+
return true;
}
+/*
+ * IPC send message
+ */
+void lamexp_ipc_send(unsigned int command, const char* message)
+{
+ if(!g_lamexp_sharedmem_ptr || !g_lamexp_semaphore_read_ptr || !g_lamexp_semaphore_write_ptr)
+ {
+ throw "Shared memory for IPC not initialized yet.";
+ }
+
+ lamexp_ipc_t *lamexp_ipc = new lamexp_ipc_t;
+ memset(lamexp_ipc, 0, sizeof(lamexp_ipc_t));
+ lamexp_ipc->command = command;
+ strcpy_s(lamexp_ipc->parameter, 4096, message);
+
+ g_lamexp_semaphore_write_ptr->acquire();
+ memcpy(g_lamexp_sharedmem_ptr->data(), lamexp_ipc, sizeof(lamexp_ipc_t));
+ g_lamexp_semaphore_read_ptr->release();
+ LAMEXP_DELETE(lamexp_ipc);
+}
+
+/*
+ * IPC read message
+ */
+void lamexp_ipc_read(unsigned int *command, char* message, size_t buffSize)
+{
+ *command = 0;
+ message[0] = '\0';
+
+ if(!g_lamexp_sharedmem_ptr || !g_lamexp_semaphore_read_ptr || !g_lamexp_semaphore_write_ptr)
+ {
+ throw "Shared memory for IPC not initialized yet.";
+ }
+
+ lamexp_ipc_t *lamexp_ipc = new lamexp_ipc_t;
+ memset(lamexp_ipc, 0, sizeof(lamexp_ipc_t));
+
+ g_lamexp_semaphore_read_ptr->acquire();
+ memcpy(lamexp_ipc, g_lamexp_sharedmem_ptr->data(), sizeof(lamexp_ipc_t));
+ g_lamexp_semaphore_write_ptr->release();
+
+ if(!(lamexp_ipc->reserved_1 || lamexp_ipc->reserved_2))
+ {
+ *command = lamexp_ipc->command;
+ strcpy_s(message, buffSize, lamexp_ipc->parameter);
+ }
+ else
+ {
+ qWarning("Malformed IPC message, will be ignored");
+ }
+
+ LAMEXP_DELETE(lamexp_ipc);
+}
+
/*
* Get LameXP temp folder
*/
@@ -361,6 +463,8 @@ void lamexp_finalization(void)
//Detach from shared memory
if(g_lamexp_sharedmem_ptr) g_lamexp_sharedmem_ptr->detach();
LAMEXP_DELETE(g_lamexp_sharedmem_ptr);
+ LAMEXP_DELETE(g_lamexp_semaphore_read_ptr);
+ LAMEXP_DELETE(g_lamexp_semaphore_write_ptr);
}
/*
diff --git a/src/Global.h b/src/Global.h
index 6c2e1957..6933ebc3 100644
--- a/src/Global.h
+++ b/src/Global.h
@@ -52,6 +52,8 @@ void lamexp_register_tool(const QString &toolName, LockedFile *file);
const QString lamexp_lookup_tool(const QString &toolName);
void lamexp_finalization(void);
const QString &lamexp_temp_folder(void);
+void lamexp_ipc_read(unsigned int *command, char* message, size_t buffSize);
+void lamexp_ipc_send(unsigned int command, const char* message);
//Auxiliary functions
bool lamexp_clean_folder(const QString folderPath);
diff --git a/src/Thread_MessageHandler.cpp b/src/Thread_MessageHandler.cpp
new file mode 100644
index 00000000..21074fa6
--- /dev/null
+++ b/src/Thread_MessageHandler.cpp
@@ -0,0 +1,56 @@
+///////////////////////////////////////////////////////////////////////////////
+// LameXP - Audio Encoder Front-End
+// Copyright (C) 2004-2010 LoRd_MuldeR
+//
+// 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 option) 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.
+//
+// http://www.gnu.org/licenses/gpl-2.0.txt
+///////////////////////////////////////////////////////////////////////////////
+
+#include "Thread_MessageHandler.h"
+
+#include "Global.h"
+
+#include
+#include
+
+////////////////////////////////////////////////////////////
+// Constructor
+////////////////////////////////////////////////////////////
+
+MessageHandlerThread::MessageHandlerThread(void)
+{
+}
+
+void MessageHandlerThread::run()
+{
+ unsigned int command = 0;
+ char *parameter = new char[4096];
+
+ while(true)
+ {
+ qDebug("MessageHandlerThread: Waiting...");
+ lamexp_ipc_read(&command, parameter, 4096);
+ qDebug("MessageHandlerThread: command=%u, parameter='%s'", command, parameter);
+ }
+
+ delete [] parameter;
+}
+
+////////////////////////////////////////////////////////////
+// EVENTS
+////////////////////////////////////////////////////////////
+
+/*NONE*/
\ No newline at end of file
diff --git a/src/Thread_MessageHandler.h b/src/Thread_MessageHandler.h
new file mode 100644
index 00000000..6ffd07b4
--- /dev/null
+++ b/src/Thread_MessageHandler.h
@@ -0,0 +1,33 @@
+///////////////////////////////////////////////////////////////////////////////
+// LameXP - Audio Encoder Front-End
+// Copyright (C) 2004-2010 LoRd_MuldeR
+//
+// 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 option) 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.
+//
+// http://www.gnu.org/licenses/gpl-2.0.txt
+///////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include
+
+class MessageHandlerThread: public QThread
+{
+ Q_OBJECT
+
+public:
+ MessageHandlerThread(void);
+ void run();
+};