23#include <core/config.h>
30#include <QLibraryInfo>
34#ifndef H2CORE_HAVE_QT6
47#ifdef H2CORE_HAVE_LASH
91 signal( nSignal, SIG_DFL );
96 ___ERRORLOG( QString(
"Fatal signal %1" ).arg( nSignal ) );
100 const int nMaxFrames = 128;
101 void *frames[ nMaxFrames ];
102 int nFrames = backtrace( frames, nMaxFrames );
103 char **symbols = backtrace_symbols( frames, nFrames );
104 for (
int i = 0; i < nFrames; i++ ) {
121 struct sigaction usr1;
124 sigemptyset(&usr1.sa_mask);
126 usr1.sa_flags |= SA_RESTART;
128 if (sigaction(SIGUSR1, &usr1,
nullptr) > 0) {
134 for (
int nSignal : { SIGSEGV, SIGILL, SIGFPE, SIGABRT,
153 app->setWindowIcon(icon);
165 : QApplication(argc, argv) {
171 if ( e->type() == QEvent::FileOpen ) {
172 QFileOpenEvent *fe =
dynamic_cast<QFileOpenEvent*
>( e );
173 assert( fe !=
nullptr );
184 return QApplication::event( e );
202int main(
int argc,
char *argv[])
208 if ( AttachConsole(ATTACH_PARENT_PROCESS)) {
209 freopen(
"CONOUT$",
"w", stdout);
210 freopen(
"CONOUT$",
"w", stderr);
211 freopen(
"CONIN$",
"w", stdin);
216#ifndef H2CORE_HAVE_QT6
217 #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
218 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
219 QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
223 QCoreApplication *pBootStrApp =
new QCoreApplication( argc, argv );
226 if ( ! parser.
parse( argc, argv ) ) {
227 std::cerr <<
"Error: Unable to parse CLI arguments. Abort..."
237 QString sInitialisingCrashContext(
"Initialising Hydrogen" );
254 ___INFOLOG( QString(
"Using QT version ") + QString( qVersion() ) );
255#ifdef H2CORE_HAVE_QT6
256 const QString sEncoding = QLocale::system().name();
258 const QString sEncoding = QTextCodec::codecForLocale()->name();
260 ___INFOLOG( QString(
"System encoding: [%1]" ).arg( sEncoding ) );
266#if QT_VERSION >= QT_VERSION_CHECK( 5, 14, 0)
268 Qt::HighDpiScaleFactorRoundingPolicy policy;
272 policy = Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor;
275 policy = Qt::HighDpiScaleFactorRoundingPolicy::PassThrough;
278 policy = Qt::HighDpiScaleFactorRoundingPolicy::Ceil;
281 QGuiApplication::setHighDpiScaleFactorRoundingPolicy( policy );
297#ifdef H2CORE_HAVE_LASH
305 ___ERRORLOG( QString(
"Unable to install drumkit [%1]" )
319 pQApp->setApplicationName(
"Hydrogen" );
324 pQApp->processEvents();
327 pQApp->setFont( QFont( family, 10 ) );
329 QTranslator qttor(
nullptr );
330 QTranslator tor(
nullptr );
331 QLocale locale = QLocale::system();
332 if ( locale != QLocale::c() ) {
333 QStringList languages;
335 if ( !sPreferredLanguage.isNull() ) {
336 languages << sPreferredLanguage;
338 languages << locale.uiLanguages();
340#ifdef H2CORE_HAVE_QT6
341 QLibraryInfo::path(QLibraryInfo::TranslationsPath) ) ) {
343 QLibraryInfo::location(QLibraryInfo::TranslationsPath) ) ) {
345 pQApp->installTranslator( &qttor );
347 ___INFOLOG( QString(
"Warning: No Qt translation for locale %1 found.").arg(locale.name()));
351 QString sTranslationFile(
"hydrogen" );
354 ___INFOLOG(
"Using locale: " + sTranslationPath );
356 ___INFOLOG(
"Warning: no locale found: " + sTranslationPath );
359 ___INFOLOG(
"Warning: error loading locale: " + sTranslationPath );
362 pQApp->installTranslator( &tor );
365 if ( !sStyle.isEmpty() ) {
366 pQApp->setStyle( sStyle );
374 QMessageBox::critical(
nullptr,
"Hydrogen",
375 QString( QT_TRANSLATE_NOOP(
"Startup",
"No [hydrogen.conf] file found. Hydrogen was not installed properly. Aborting..." ) ) );
385 ___ERRORLOG(
"No preferences file found. Aborting..." );
391#ifdef H2CORE_HAVE_APPIMAGE
404 QString sCurrentDir = QDir::currentPath();
405 QDir::setCurrent( QCoreApplication::applicationDirPath() );
407 process.start(
"openssl", QStringList(
"version" ));
408 process.waitForFinished(-1);
409 QString sStdout = process.readAllStandardOutput();
410 ___INFOLOG( QString(
"current: %1, application: %2" ).arg( sCurrentDir )
411 .arg( QCoreApplication::applicationDirPath() ) );
412 ___INFOLOG( QString(
"OpenSSL supported: [%1], version OS: [%2], Qt runtime: [%3], Qt build: [%4]" )
413 .arg( QSslSocket::supportsSsl() )
414 .arg( sStdout.trimmed() )
415 .arg( QSslSocket::sslLibraryVersionString() )
416 .arg( QSslSocket::sslLibraryBuildVersionString() ) );
417 QDir::setCurrent( sCurrentDir );
422#ifdef H2CORE_HAVE_OSC
432#ifndef H2CORE_HAVE_OSC
436#ifdef H2CORE_HAVE_LASH
441 if (lash_event && lash_event_get_type(lash_event) == LASH_Restore_File)
447 sSongFilename.append( QString::fromLocal8Bit(lash_event_get_string(lash_event)) );
448 sSongFilename.append(
"/hydrogen.h2song");
452 lash_event_destroy(lash_event);
457 lash_event_destroy(lash_event);
470 pHydrogen->startNsmClient();
478 if ( pHydrogen->getAudioOutput() ==
nullptr ) {
481 QApplication::setOverrideCursor( Qt::WaitCursor );
482 pHydrogen->restartDrivers();
483 QApplication::restoreOverrideCursor();
490 pSplash->finish( pMainForm );
493 bool bLoadlist = pHydrogenApp->getPlayListDialog()->loadListByFileName(
504 pHydrogen->getCoreActionController()->setDrumkit(
527 if ( pHydrogen->getSong()->getFilename() !=
529#ifdef H2CORE_HAVE_OSC
538 pHydrogen->setIsModified(
true );
542 pHydrogen->setIsModified(
false );
545 pHydrogen->setIsModified(
false );
553 QString sShutdownCrashContext(
"Shutting down Hydrogen" );
567 std::cout <<
"\nBye..." << std::endl;
576 std::cerr <<
"[main] Exception: " << ex.what() << std::endl;
580 std::cerr <<
"[main] Unknown exception X-(" << std::endl;
static void write_objects_map_to_cerr()
output objects map to stderr
static bool count_active()
static int bootstrap(Logger *logger, bool count=false)
must be called before any Object instantiation !
static bool install(const QString &sSourcePath, const QString &sTargetPath="", QString *pInstalledPath=nullptr, bool *pEncodingIssuesDetected=nullptr, bool bSilent=false)
Extract a .h2drumkit file.
static EventQueue * get_instance()
Returns a pointer to the current EventQueue singleton stored in __instance.
static QString sys_data_path()
returns system data path
static bool bootstrap(Logger *logger, const QString &sSysDataPath="", const QString &sUsrDataPath="", const QString &sUserConfigFile="", const QString &sLogFile="")
check user and system filesystem usability
static QString empty_song_path()
Provides the full path to the current empty song.
static QString i18n_dir()
returns internationalization path
@ notReady
There is a GUI but it is not ready yet (during startup).
@ ready
There is a working GUI.
static void create_instance()
Creates all the instances used within Hydrogen in the right order.
static Hydrogen * get_instance()
Returns the current Hydrogen instance __instance.
Class for writing logs to the console.
static Logger * bootstrap(unsigned msk, const QString &sLogFilePath=QString(), bool bUseStdout=true, bool bLogTimestamps=false, bool bLogColors=true)
create the logger instance if not exists, set the log level and return the instance
static Logger * get_instance()
Returns a pointer to the current H2Core::Logger singleton stored in __instance.
static void setCrashContext(QString *pContext)
void setNextSongByNumber(int SongNumber)
static Playlist * get_instance()
Returns a pointer to the current Playlist singleton stored in __instance.
Manager for User Preferences File (singleton)
static AudioDriver parseAudioDriver(const QString &sDriver)
static Preferences * get_instance()
Returns a pointer to the current Preferences singleton stored in __instance.
const QString & getApplicationFontFamily() const
const QString & getQTStyle()
bool savePreferences()
Save the preferences file.
static void create_instance()
If __instance equals 0, a new Preferences singleton will be created and stored in it.
AudioDriver m_audioDriver
Audio driver.
const QString & getPreferredLanguage()
bool getLoadingSuccessful() const
InterfaceTheme::ScalingPolicy getUIScalingPolicy()
void setDefaultUILayout(InterfaceTheme::Layout layout)
int m_nOscTemporaryPort
In case m_nOscServerPort is already occupied by another client, the alternative - random - port numbe...
void setH2ProcessName(const QString &processName)
static bool loadTranslation(QStringList languages, QTranslator &tor, QString sFileName, QString sDirectory=H2Core::Filesystem::i18n_dir())
QString m_sInitialFileOpen
bool event(QEvent *e) override
H2QApplication(int &argc, char **argv)
void setMainForm(QWidget *pMainForm)
static HydrogenApp * get_instance()
Returns the instance of HydrogenApp class.
static void create_instance(const char *lashClass, const char *viewName, int *argc, char ***argv)
static reference of LashClient class (Singleton)
lash_event_t * getNextEvent()
static LashClient * get_instance()
void setNewProject(bool value)
static void usr1SignalHandler(int unused)
static MidiActionManager * get_instance()
Returns a pointer to the current MidiActionManager singleton stored in __instance.
static void create_instance()
If __instance equals 0, a new MidiMap singleton will be created and stored in it.
static MidiMap * get_instance()
Returns a pointer to the current MidiMap singleton stored in __instance.
void sendDirtyState(const bool isDirty)
Informs the NSM server whether the current H2Core::Song is modified or not.
static NsmClient * get_instance()
Reusable parser for provided command line arguments.
bool getLogColors() const
const QString & getUiLayout() const
const QString & getLogFile() const
const QString & getShotList() const
const QString & getSysDataPath() const
const QString & getDrumkitToLoad() const
unsigned getLogLevel() const
const QString & getInstallDrumkitPath() const
const QString & getSongFilename() const
const QString & getAudioDriver() const
bool getNoSplashScreen() const
bool parse(int argc, char *argv[])
bool getLogTimestamps() const
const QString & getPlaylistFilename() const
const QString & getConfigFilePath() const
const QString & getUsrDataPath() const
static void report(void)
Report some crash details in a crashing child (mostly, the Logger 'crash context' string)
static void spawn(int argc, char *argv[])
Potentially spawn child process.
static void setPalette(QApplication *pQApp)
Function used to update the global palette of the QApplication.
static QString getImagePath()
int main(int argc, char *argv[])
static int setup_unix_signal_handlers()
static void setApplicationIcon(QApplication *app)
static void handleFatalSignal(int nSignal)
std::string get_version()
Returns the current Hydrogen version string.
void init_gui_object_map()