Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

carla_shared.cpp 20KB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. /*
  2. * Common Carla code
  3. * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "carla_shared.hpp"
  18. #include <QtCore/QDir>
  19. #include <QtCore/QFile>
  20. #include <QtWidgets/QFileDialog>
  21. #include <QtWidgets/QLineEdit>
  22. //#ifdef CARLA_OS_MAC
  23. //#endif
  24. CARLA_BACKEND_USE_NAMESPACE
  25. // ------------------------------------------------------------------------------------------------------------
  26. // Misc functions
  27. static
  28. QString getenvWithFallback(const char* const key, const QString& fallback)
  29. {
  30. if (const char* const value = std::getenv(key))
  31. return key;
  32. return fallback;
  33. }
  34. // ------------------------------------------------------------------------------------------------------------
  35. // Global objects
  36. QString TMP;
  37. QString HOME;
  38. QStringList PATH;
  39. QStringList MIDI_CC_LIST;
  40. CarlaObject gCarla;
  41. // ------------------------------------------------------------------------------------------------------------
  42. // init
  43. static
  44. void init()
  45. {
  46. // --------------------------------------------------------------------------------------------------------
  47. // Platform specific stuff
  48. #if defined(CARLA_OS_MAC)
  49. qt_mac_set_menubar_icons(false);
  50. #elif defined(CARLA_OS_WIN)
  51. QString WINDIR = std::getenv("WINDIR");
  52. #endif
  53. // --------------------------------------------------------------------------------------------------------
  54. // Set TMP
  55. const char* const envTMP = std::getenv("TMP");
  56. if (envTMP == nullptr)
  57. {
  58. #ifdef CARLA_OS_WIN
  59. qWarning("TMP variable not set");
  60. #endif
  61. TMP = QDir::tempPath();
  62. }
  63. else
  64. TMP = envTMP;
  65. if (! QDir(TMP).exists())
  66. {
  67. qWarning("TMP does not exist");
  68. TMP = "/";
  69. }
  70. // --------------------------------------------------------------------------------------------------------
  71. // Set HOME
  72. const char* const envHOME = std::getenv("HOME");
  73. if (envHOME == nullptr)
  74. {
  75. #if defined(CARLA_OS_LINUX) || defined(CARLA_OS_MAC)
  76. qWarning("HOME variable not set");
  77. #endif
  78. HOME = QDir::homePath();
  79. }
  80. else
  81. HOME = envHOME;
  82. if (! QDir(HOME).exists())
  83. {
  84. qWarning("HOME does not exist");
  85. HOME = TMP;
  86. }
  87. // --------------------------------------------------------------------------------------------------------
  88. // Set PATH
  89. const char* const envPATH = std::getenv("PATH");
  90. if (envPATH == nullptr)
  91. {
  92. qWarning("PATH variable not set");
  93. PATH.clear();
  94. #if defined(CARLA_OS_MAC)
  95. PATH << "/opt/local/bin";
  96. PATH << "/usr/local/bin";
  97. PATH << "/usr/bin";
  98. PATH << "/bin";
  99. #elif defined(CARLA_OS_WIN)
  100. PATH << QDir(WINDIR).filePath("system32");
  101. PATH << WINDIR;
  102. #else
  103. PATH << "/usr/local/bin";
  104. PATH << "/usr/bin";
  105. PATH << "/bin";
  106. #endif
  107. }
  108. else
  109. {
  110. #ifdef CARLA_OS_WIN
  111. PATH = QString(envPATH).split(":");
  112. #else
  113. PATH = QString(envPATH).split(";");
  114. #endif
  115. }
  116. // --------------------------------------------------------------------------------------------------------
  117. // Static MIDI CC list
  118. MIDI_CC_LIST.clear();
  119. MIDI_CC_LIST << "0x01 Modulation";
  120. MIDI_CC_LIST << "0x02 Breath";
  121. MIDI_CC_LIST << "0x03 (Undefined)";
  122. MIDI_CC_LIST << "0x04 Foot";
  123. MIDI_CC_LIST << "0x05 Portamento";
  124. MIDI_CC_LIST << "0x07 Volume";
  125. MIDI_CC_LIST << "0x08 Balance";
  126. MIDI_CC_LIST << "0x09 (Undefined)";
  127. MIDI_CC_LIST << "0x0A Pan";
  128. MIDI_CC_LIST << "0x0B Expression";
  129. MIDI_CC_LIST << "0x0C FX Control 1";
  130. MIDI_CC_LIST << "0x0D FX Control 2";
  131. MIDI_CC_LIST << "0x0E (Undefined)";
  132. MIDI_CC_LIST << "0x0F (Undefined)";
  133. MIDI_CC_LIST << "0x10 General Purpose 1";
  134. MIDI_CC_LIST << "0x11 General Purpose 2";
  135. MIDI_CC_LIST << "0x12 General Purpose 3";
  136. MIDI_CC_LIST << "0x13 General Purpose 4";
  137. MIDI_CC_LIST << "0x14 (Undefined)";
  138. MIDI_CC_LIST << "0x15 (Undefined)";
  139. MIDI_CC_LIST << "0x16 (Undefined)";
  140. MIDI_CC_LIST << "0x17 (Undefined)";
  141. MIDI_CC_LIST << "0x18 (Undefined)";
  142. MIDI_CC_LIST << "0x19 (Undefined)";
  143. MIDI_CC_LIST << "0x1A (Undefined)";
  144. MIDI_CC_LIST << "0x1B (Undefined)";
  145. MIDI_CC_LIST << "0x1C (Undefined)";
  146. MIDI_CC_LIST << "0x1D (Undefined)";
  147. MIDI_CC_LIST << "0x1E (Undefined)";
  148. MIDI_CC_LIST << "0x1F (Undefined)";
  149. MIDI_CC_LIST << "0x46 Control 1 [Variation]";
  150. MIDI_CC_LIST << "0x47 Control 2 [Timbre]";
  151. MIDI_CC_LIST << "0x48 Control 3 [Release]";
  152. MIDI_CC_LIST << "0x49 Control 4 [Attack]";
  153. MIDI_CC_LIST << "0x4A Control 5 [Brightness]";
  154. MIDI_CC_LIST << "0x4B Control 6 [Decay]";
  155. MIDI_CC_LIST << "0x4C Control 7 [Vib Rate]";
  156. MIDI_CC_LIST << "0x4D Control 8 [Vib Depth]";
  157. MIDI_CC_LIST << "0x4E Control 9 [Vib Delay]";
  158. MIDI_CC_LIST << "0x4F Control 10 [Undefined]";
  159. MIDI_CC_LIST << "0x50 General Purpose 5";
  160. MIDI_CC_LIST << "0x51 General Purpose 6";
  161. MIDI_CC_LIST << "0x52 General Purpose 7";
  162. MIDI_CC_LIST << "0x53 General Purpose 8";
  163. MIDI_CC_LIST << "0x54 Portamento Control";
  164. MIDI_CC_LIST << "0x5B FX 1 Depth [Reverb]";
  165. MIDI_CC_LIST << "0x5C FX 2 Depth [Tremolo]";
  166. MIDI_CC_LIST << "0x5D FX 3 Depth [Chorus]";
  167. MIDI_CC_LIST << "0x5E FX 4 Depth [Detune]";
  168. MIDI_CC_LIST << "0x5F FX 5 Depth [Phaser]";
  169. // --------------------------------------------------------------------------------------------------------
  170. // Global Carla object
  171. gCarla.host = nullptr;
  172. gCarla.gui = nullptr;
  173. gCarla.isControl = false;
  174. gCarla.isLocal = true;
  175. gCarla.isPlugin = false;
  176. gCarla.bufferSize = 0;
  177. gCarla.sampleRate = 0.0;
  178. #ifdef CARLA_OS_LINUX
  179. gCarla.processMode = CarlaBackend::ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS;
  180. #else
  181. gCarla.processMode = CarlaBackend::ENGINE_PROCESS_MODE_CONTINUOUS_RACK;
  182. #endif
  183. gCarla.processModeForced = false;
  184. #ifdef CARLA_OS_LINUX
  185. gCarla.transportMode = CarlaBackend::ENGINE_TRANSPORT_MODE_JACK;
  186. #else
  187. gCarla.transportMode = CarlaBackend::ENGINE_TRANSPORT_MODE_INTERNAL;
  188. #endif
  189. gCarla.maxParameters = CarlaBackend::MAX_DEFAULT_PARAMETERS;
  190. gCarla.pathBinaries = "";
  191. gCarla.pathResources = "";
  192. // --------------------------------------------------------------------------------------------------------
  193. // Default Plugin Folders (get)
  194. QString splitter;
  195. QString DEFAULT_LADSPA_PATH, DEFAULT_DSSI_PATH, DEFAULT_LV2_PATH, DEFAULT_VST_PATH, DEFAULT_VST3_PATH, DEFAULT_AU_PATH;
  196. QString DEFAULT_CSOUND_PATH, DEFAULT_GIG_PATH, DEFAULT_SF2_PATH, DEFAULT_SFZ_PATH;
  197. #if defined(CARLA_OS_WIN)
  198. splitter = ";";
  199. const char* const envAPPDATA = std::getenv("APPDATA");
  200. const char* const envPROGRAMFILES = std::getenv("PROGRAMFILES");
  201. const char* const envPROGRAMFILESx86 = std::getenv("PROGRAMFILES(x86)");
  202. const char* const envCOMMONPROGRAMFILES = std::getenv("COMMONPROGRAMFILES");
  203. // Small integrity tests
  204. if (envAPPDATA == nullptr)
  205. {
  206. qFatal("APPDATA variable not set, cannot continue");
  207. std::exit(1);
  208. }
  209. if (envPROGRAMFILES == nullptr)
  210. {
  211. qFatal("PROGRAMFILES variable not set, cannot continue");
  212. std::exit(1);
  213. }
  214. if (envCOMMONPROGRAMFILES == nullptr)
  215. {
  216. qFatal("COMMONPROGRAMFILES variable not set, cannot continue");
  217. std::exit(1);
  218. }
  219. QString APPDATA(envAPPDATA);
  220. QString PROGRAMFILES(envPROGRAMFILES);
  221. QString COMMONPROGRAMFILES(envCOMMONPROGRAMFILES);
  222. DEFAULT_LADSPA_PATH = APPDATA + "\\LADSPA";
  223. DEFAULT_LADSPA_PATH += ";" + PROGRAMFILES + "\\LADSPA";
  224. DEFAULT_DSSI_PATH = APPDATA + "\\DSSI";
  225. DEFAULT_DSSI_PATH += ";" + PROGRAMFILES + "\\DSSI";
  226. DEFAULT_LV2_PATH = APPDATA + "\\LV2";
  227. DEFAULT_LV2_PATH += ";" + COMMONPROGRAMFILES + "\\LV2";
  228. DEFAULT_VST_PATH = PROGRAMFILES + "\\VstPlugins";
  229. DEFAULT_VST_PATH += ";" + PROGRAMFILES + "\\Steinberg\\VstPlugins";
  230. DEFAULT_VST3_PATH = PROGRAMFILES + "\\Vst3";
  231. DEFAULT_GIG_PATH = APPDATA + "\\GIG";
  232. DEFAULT_SF2_PATH = APPDATA + "\\SF2";
  233. DEFAULT_SFZ_PATH = APPDATA + "\\SFZ";
  234. if (envPROGRAMFILESx86 != nullptr)
  235. {
  236. QString PROGRAMFILESx86(envPROGRAMFILESx86);
  237. DEFAULT_LADSPA_PATH += ";" + PROGRAMFILESx86 + "\\LADSPA";
  238. DEFAULT_DSSI_PATH += ";" + PROGRAMFILESx86 + "\\DSSI";
  239. DEFAULT_VST_PATH += ";" + PROGRAMFILESx86 + "\\VstPlugins";
  240. DEFAULT_VST_PATH += ";" + PROGRAMFILESx86 + "\\Steinberg\\VstPlugins";
  241. }
  242. #elif defined(CARLA_OS_HAIKU)
  243. splitter = ":";
  244. DEFAULT_LADSPA_PATH = HOME + "/.ladspa";
  245. DEFAULT_LADSPA_PATH += ":/boot/common/add-ons/ladspa";
  246. DEFAULT_DSSI_PATH = HOME + "/.dssi";
  247. DEFAULT_DSSI_PATH += ":/boot/common/add-ons/dssi";
  248. DEFAULT_LV2_PATH = HOME + "/.lv2";
  249. DEFAULT_LV2_PATH += ":/boot/common/add-ons/lv2";
  250. DEFAULT_VST_PATH = HOME + "/.vst";
  251. DEFAULT_VST_PATH += ":/boot/common/add-ons/vst";
  252. DEFAULT_VST3_PATH = HOME + "/.vst3";
  253. DEFAULT_VST3_PATH += ":/boot/common/add-ons/vst3";
  254. #elif defined(CARLA_OS_MAC)
  255. splitter = ":";
  256. DEFAULT_LADSPA_PATH = HOME + "/Library/Audio/Plug-Ins/LADSPA";
  257. DEFAULT_LADSPA_PATH += ":/Library/Audio/Plug-Ins/LADSPA";
  258. DEFAULT_DSSI_PATH = HOME + "/Library/Audio/Plug-Ins/DSSI";
  259. DEFAULT_DSSI_PATH += ":/Library/Audio/Plug-Ins/DSSI";
  260. DEFAULT_LV2_PATH = HOME + "/Library/Audio/Plug-Ins/LV2";
  261. DEFAULT_LV2_PATH += ":/Library/Audio/Plug-Ins/LV2";
  262. DEFAULT_VST_PATH = HOME + "/Library/Audio/Plug-Ins/VST";
  263. DEFAULT_VST_PATH += ":/Library/Audio/Plug-Ins/VST";
  264. DEFAULT_VST3_PATH = HOME + "/Library/Audio/Plug-Ins/VST3";
  265. DEFAULT_VST3_PATH += ":/Library/Audio/Plug-Ins/VST3";
  266. DEFAULT_AU_PATH = HOME + "/Library/Audio/Plug-Ins/Components";
  267. DEFAULT_AU_PATH += ":/Library/Audio/Plug-Ins/Components";
  268. #else
  269. splitter = ":";
  270. DEFAULT_LADSPA_PATH = HOME + "/.ladspa";
  271. DEFAULT_LADSPA_PATH += ":/usr/lib/ladspa";
  272. DEFAULT_LADSPA_PATH += ":/usr/local/lib/ladspa";
  273. DEFAULT_DSSI_PATH = HOME + "/.dssi";
  274. DEFAULT_DSSI_PATH += ":/usr/lib/dssi";
  275. DEFAULT_DSSI_PATH += ":/usr/local/lib/dssi";
  276. DEFAULT_LV2_PATH = HOME + "/.lv2";
  277. DEFAULT_LV2_PATH += ":/usr/lib/lv2";
  278. DEFAULT_LV2_PATH += ":/usr/local/lib/lv2";
  279. DEFAULT_VST_PATH = HOME + "/.vst";
  280. DEFAULT_VST_PATH += ":/usr/lib/vst";
  281. DEFAULT_VST_PATH += ":/usr/local/lib/vst";
  282. DEFAULT_VST3_PATH = HOME + "/.vst3";
  283. DEFAULT_VST3_PATH += ":/usr/lib/vst3";
  284. DEFAULT_VST3_PATH += ":/usr/local/lib/vst3";
  285. DEFAULT_GIG_PATH = HOME + "/.sounds/gig";
  286. DEFAULT_GIG_PATH += ":/usr/share/sounds/gig";
  287. DEFAULT_SF2_PATH = HOME + "/.sounds/sf2";
  288. DEFAULT_SF2_PATH += ":/usr/share/sounds/sf2";
  289. DEFAULT_SFZ_PATH = HOME + "/.sounds/sfz";
  290. DEFAULT_SFZ_PATH += ":/usr/share/sounds/sfz";
  291. #endif
  292. #ifndef CARLA_OS_WIN
  293. QString winePrefix = std::getenv("WINEPREFIX");
  294. if (winePrefix.isEmpty())
  295. winePrefix = HOME + "/.wine";
  296. if (QDir(winePrefix).exists())
  297. {
  298. DEFAULT_VST_PATH += ":" + winePrefix + "/drive_c/Program Files/VstPlugins";
  299. DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files/Common Files/VST3";
  300. # if defined (__LP64__) || defined (_LP64)
  301. if (QDir(winePrefix + "/drive_c/Program Files (x86)").exists())
  302. {
  303. DEFAULT_VST_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/VstPlugins";
  304. DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/VST3";
  305. }
  306. # endif
  307. }
  308. #endif
  309. // --------------------------------------------------------------------------------------------------------
  310. // Default Plugin Folders (set)
  311. bool readEnvVars = true;
  312. #if 0 //def CARLA_OS_WIN
  313. // Check if running Wine. If yes, ignore env vars
  314. from winreg import ConnectRegistry, OpenKey, CloseKey, HKEY_CURRENT_USER;
  315. reg = ConnectRegistry(None, HKEY_CURRENT_USER);
  316. key = OpenKey(reg, r"SOFTWARE\Wine");
  317. CloseKey(key);
  318. readEnvVars = False;
  319. CloseKey(reg);
  320. #endif
  321. if (readEnvVars)
  322. {
  323. gCarla.DEFAULT_LADSPA_PATH = getenvWithFallback("LADSPA_PATH", DEFAULT_LADSPA_PATH).split(splitter);
  324. gCarla.DEFAULT_DSSI_PATH = getenvWithFallback("DSSI_PATH", DEFAULT_DSSI_PATH).split(splitter);
  325. gCarla.DEFAULT_LV2_PATH = getenvWithFallback("LV2_PATH", DEFAULT_LV2_PATH).split(splitter);
  326. gCarla.DEFAULT_VST_PATH = getenvWithFallback("VST_PATH", DEFAULT_VST_PATH).split(splitter);
  327. gCarla.DEFAULT_VST3_PATH = getenvWithFallback("VST3_PATH", DEFAULT_VST3_PATH).split(splitter);
  328. gCarla.DEFAULT_AU_PATH = getenvWithFallback("AU_PATH", DEFAULT_AU_PATH).split(splitter);
  329. gCarla.DEFAULT_CSOUND_PATH = getenvWithFallback("CSOUND_PATH", DEFAULT_CSOUND_PATH).split(splitter);
  330. gCarla.DEFAULT_GIG_PATH = getenvWithFallback("GIG_PATH", DEFAULT_GIG_PATH).split(splitter);
  331. gCarla.DEFAULT_SF2_PATH = getenvWithFallback("SF2_PATH", DEFAULT_SF2_PATH).split(splitter);
  332. gCarla.DEFAULT_SFZ_PATH = getenvWithFallback("SFZ_PATH", DEFAULT_SFZ_PATH).split(splitter);
  333. }
  334. else
  335. {
  336. gCarla.DEFAULT_LADSPA_PATH = DEFAULT_LADSPA_PATH.split(splitter);
  337. gCarla.DEFAULT_DSSI_PATH = DEFAULT_DSSI_PATH.split(splitter);
  338. gCarla.DEFAULT_LV2_PATH = DEFAULT_LV2_PATH.split(splitter);
  339. gCarla.DEFAULT_VST_PATH = DEFAULT_VST_PATH.split(splitter);
  340. gCarla.DEFAULT_VST3_PATH = DEFAULT_VST3_PATH.split(splitter);
  341. gCarla.DEFAULT_AU_PATH = DEFAULT_AU_PATH.split(splitter);
  342. gCarla.DEFAULT_CSOUND_PATH = DEFAULT_CSOUND_PATH.split(splitter);
  343. gCarla.DEFAULT_GIG_PATH = DEFAULT_GIG_PATH.split(splitter);
  344. gCarla.DEFAULT_SF2_PATH = DEFAULT_SF2_PATH.split(splitter);
  345. gCarla.DEFAULT_SFZ_PATH = DEFAULT_SFZ_PATH.split(splitter);
  346. }
  347. }
  348. // ------------------------------------------------------------------------------------------------------------
  349. // find tool
  350. QString findTool(const QString& toolName)
  351. {
  352. QString path;
  353. path = QDir::current().filePath(toolName);
  354. if (QFile(path).exists())
  355. return path;
  356. if (! gCarla.pathBinaries.isEmpty())
  357. {
  358. path = QDir(gCarla.pathBinaries).filePath(toolName);
  359. if (QFile(path).exists())
  360. return path;
  361. }
  362. foreach (const QString& p, PATH)
  363. {
  364. path = QDir(p).filePath(toolName);
  365. if (QFile(path).exists())
  366. return path;
  367. }
  368. return "";
  369. }
  370. // ------------------------------------------------------------------------------------------------------------
  371. // Init host
  372. void initHost(const char* const initName, const char* const libPrefix, bool failError)
  373. {
  374. init();
  375. // -------------------------------------------------------------
  376. // Set Carla library name
  377. QString libname = "libcarla_";
  378. if (gCarla.isControl)
  379. libname += "control2";
  380. else
  381. libname += "standalone2";
  382. #if defined(CARLA_OS_WIN)
  383. libname += ".dll";
  384. #elif defined(CARLA_OS_MAC)
  385. libname += ".dylib";
  386. #else
  387. libname += ".so";
  388. #endif
  389. // -------------------------------------------------------------
  390. // Set binary dir
  391. QString CWD = QDir::current().absolutePath();
  392. if (libPrefix != nullptr && libPrefix[0] != '\0')
  393. {
  394. QDir tmp(libPrefix);
  395. tmp.cd("lib");
  396. tmp.cd("carla");
  397. gCarla.pathBinaries = tmp.absolutePath();
  398. }
  399. else if (CWD.endsWith("resources", Qt::CaseInsensitive))
  400. {
  401. QDir tmp(CWD);
  402. tmp.cdUp();
  403. gCarla.pathBinaries = tmp.absolutePath();
  404. }
  405. else if (CWD.endsWith("source", Qt::CaseInsensitive))
  406. {
  407. QDir tmp(CWD);
  408. tmp.cdUp();
  409. tmp.cd("bin");
  410. gCarla.pathBinaries = tmp.absolutePath();
  411. }
  412. else if (CWD.endsWith("bin", Qt::CaseInsensitive))
  413. {
  414. gCarla.pathBinaries = CWD;
  415. }
  416. // -------------------------------------------------------------
  417. // Fail if binary dir is not found
  418. if (gCarla.pathBinaries.isEmpty() && ! gCarla.isPlugin)
  419. {
  420. if (failError)
  421. {
  422. QMessageBox::critical(nullptr, "Error", "Failed to find the carla library, cannot continue");
  423. std::exit(1);
  424. }
  425. return;
  426. }
  427. // -------------------------------------------------------------
  428. // Set resources dir
  429. if (libPrefix != nullptr && libPrefix[0] != '\0')
  430. {
  431. QDir tmp(libPrefix);
  432. tmp.cd("share");
  433. tmp.cd("carla");
  434. tmp.cd("resources");
  435. gCarla.pathResources = tmp.absolutePath();
  436. }
  437. else
  438. {
  439. QDir tmp(gCarla.pathBinaries);
  440. tmp.cd("resources");
  441. gCarla.pathResources = tmp.absolutePath();
  442. }
  443. // -------------------------------------------------------------
  444. // Print info
  445. carla_stdout("Carla %s started, status:", VERSION);
  446. carla_stdout(" binary dir: %s", gCarla.pathBinaries.toUtf8().constData());
  447. carla_stdout(" resources dir: %s", gCarla.pathResources.toUtf8().constData());
  448. // -------------------------------------------------------------
  449. // Init host
  450. if (! (gCarla.isControl or gCarla.isPlugin))
  451. carla_set_engine_option(ENGINE_OPTION_NSM_INIT, getpid(), initName);
  452. carla_set_engine_option(ENGINE_OPTION_PATH_BINARIES, 0, gCarla.pathBinaries.toUtf8().constData());
  453. carla_set_engine_option(ENGINE_OPTION_PATH_RESOURCES, 0, gCarla.pathResources.toUtf8().constData());
  454. }
  455. // ------------------------------------------------------------------------------------------------------------
  456. // Get Icon from user theme, using our own as backup (Oxygen)
  457. QIcon getIcon(const QString& icon, const int size)
  458. {
  459. return QIcon::fromTheme(icon, QIcon(QString(":/%ix%i/%s.png").arg(size).arg(size).arg(icon)));
  460. }
  461. // ------------------------------------------------------------------------------------------------------------
  462. // Signal handler
  463. static inline // TODO - remove inline
  464. void signalHandler(/*sig, frame*/)
  465. {
  466. if (gCarla.gui == nullptr)
  467. return;
  468. // if (sig == SIGINT || sig == SIGTERM)
  469. // emit(gCarla.gui.SIGTERM);
  470. #ifdef HAVE_SIGUSR1
  471. // else if (sig == SIGUSR1)
  472. // emit(gCarla.gui.SIGUSR1);
  473. #endif
  474. }
  475. void setUpSignals()
  476. {
  477. //signal(SIGINT, signalHandler);
  478. //signal(SIGTERM, signalHandler);
  479. #ifdef HAVE_SIGUSR1
  480. //signal(SIGUSR1, signalHandler);
  481. #endif
  482. }
  483. // ------------------------------------------------------------------------------------------------------------
  484. // QLineEdit and QPushButton combo
  485. QString getAndSetPath(QWidget* const parent, const QString& currentPath, QLineEdit* const lineEdit)
  486. {
  487. QString newPath = QFileDialog::getExistingDirectory(parent, parent->tr("Set Path"), currentPath, QFileDialog::ShowDirsOnly);
  488. if (! newPath.isEmpty())
  489. lineEdit->setText(newPath);
  490. return newPath;
  491. }
  492. // ------------------------------------------------------------------------------------------------------------
  493. // Custom MessageBox
  494. int CustomMessageBox(QWidget* const parent, const QMessageBox::Icon icon, const QString& title, const QString& text, const QString& extraText, const QMessageBox::StandardButtons buttons, const QMessageBox::StandardButton defButton)
  495. {
  496. QMessageBox msgBox(parent);
  497. msgBox.setIcon(icon);
  498. msgBox.setWindowTitle(title);
  499. msgBox.setText(text);
  500. msgBox.setInformativeText(extraText);
  501. msgBox.setStandardButtons(buttons);
  502. msgBox.setDefaultButton(defButton);
  503. return msgBox.exec();
  504. }
  505. // ------------------------------------------------------------------------------------------------------------